From c2f2c168928e96c71f21b638b5dfcc0587ade54c Mon Sep 17 00:00:00 2001 From: Jeffrey Gelens Date: Mon, 16 Mar 2015 13:13:40 +0100 Subject: [PATCH 1/3] Fixed non threadsafe code --- moto/autoscaling/urls.py | 2 +- moto/cloudformation/urls.py | 2 +- moto/cloudwatch/urls.py | 2 +- moto/core/responses.py | 6 +++++- moto/dynamodb/urls.py | 2 +- moto/dynamodb2/urls.py | 2 +- moto/ec2/urls.py | 2 +- moto/elb/urls.py | 2 +- moto/emr/urls.py | 2 +- moto/iam/urls.py | 2 +- moto/kinesis/urls.py | 2 +- moto/rds/urls.py | 2 +- moto/rds2/urls.py | 2 +- moto/redshift/urls.py | 2 +- moto/server.py | 10 +++++++++- moto/ses/urls.py | 2 +- moto/sns/urls.py | 2 +- moto/sqs/urls.py | 4 ++-- moto/sts/urls.py | 2 +- 19 files changed, 32 insertions(+), 20 deletions(-) diff --git a/moto/autoscaling/urls.py b/moto/autoscaling/urls.py index 336cade3f..0743fdcf7 100644 --- a/moto/autoscaling/urls.py +++ b/moto/autoscaling/urls.py @@ -6,5 +6,5 @@ url_bases = [ ] url_paths = { - '{0}/$': AutoScalingResponse().dispatch, + '{0}/$': AutoScalingResponse.dispatch, } diff --git a/moto/cloudformation/urls.py b/moto/cloudformation/urls.py index f2cfb0205..468c68d98 100644 --- a/moto/cloudformation/urls.py +++ b/moto/cloudformation/urls.py @@ -6,5 +6,5 @@ url_bases = [ ] url_paths = { - '{0}/$': CloudFormationResponse().dispatch, + '{0}/$': CloudFormationResponse.dispatch, } diff --git a/moto/cloudwatch/urls.py b/moto/cloudwatch/urls.py index 2371f09cb..0a9101cfb 100644 --- a/moto/cloudwatch/urls.py +++ b/moto/cloudwatch/urls.py @@ -5,5 +5,5 @@ url_bases = [ ] url_paths = { - '{0}/$': CloudWatchResponse().dispatch, + '{0}/$': CloudWatchResponse.dispatch, } diff --git a/moto/core/responses.py b/moto/core/responses.py index a99ac78c8..bd54cf01c 100644 --- a/moto/core/responses.py +++ b/moto/core/responses.py @@ -82,7 +82,11 @@ class BaseResponse(_TemplateEnvironmentMixin): default_region = 'us-east-1' region_regex = r'\.(.+?)\.amazonaws\.com' - def dispatch(self, request, full_url, headers): + @classmethod + def dispatch(cls, *args, **kwargs): + return cls()._dispatch(*args, **kwargs) + + def _dispatch(self, request, full_url, headers): querystring = {} if hasattr(request, 'body'): diff --git a/moto/dynamodb/urls.py b/moto/dynamodb/urls.py index 1afd34354..66c15d022 100644 --- a/moto/dynamodb/urls.py +++ b/moto/dynamodb/urls.py @@ -7,5 +7,5 @@ url_bases = [ ] url_paths = { - "{0}/": DynamoHandler().dispatch, + "{0}/": DynamoHandler.dispatch, } diff --git a/moto/dynamodb2/urls.py b/moto/dynamodb2/urls.py index 1afd34354..66c15d022 100644 --- a/moto/dynamodb2/urls.py +++ b/moto/dynamodb2/urls.py @@ -7,5 +7,5 @@ url_bases = [ ] url_paths = { - "{0}/": DynamoHandler().dispatch, + "{0}/": DynamoHandler.dispatch, } diff --git a/moto/ec2/urls.py b/moto/ec2/urls.py index e27689087..768a8cd3b 100644 --- a/moto/ec2/urls.py +++ b/moto/ec2/urls.py @@ -7,5 +7,5 @@ url_bases = [ ] url_paths = { - '{0}/': EC2Response().dispatch, + '{0}/': EC2Response.dispatch, } diff --git a/moto/elb/urls.py b/moto/elb/urls.py index ee7703ff1..48fcb37ab 100644 --- a/moto/elb/urls.py +++ b/moto/elb/urls.py @@ -6,5 +6,5 @@ url_bases = [ ] url_paths = { - '{0}/$': ELBResponse().dispatch, + '{0}/$': ELBResponse.dispatch, } diff --git a/moto/emr/urls.py b/moto/emr/urls.py index 0daa41e0d..83eb62b28 100644 --- a/moto/emr/urls.py +++ b/moto/emr/urls.py @@ -6,5 +6,5 @@ url_bases = [ ] url_paths = { - '{0}/$': ElasticMapReduceResponse().dispatch, + '{0}/$': ElasticMapReduceResponse.dispatch, } diff --git a/moto/iam/urls.py b/moto/iam/urls.py index 8c05a6f0e..a591e3ebe 100644 --- a/moto/iam/urls.py +++ b/moto/iam/urls.py @@ -6,5 +6,5 @@ url_bases = [ ] url_paths = { - '{0}/$': IamResponse().dispatch, + '{0}/$': IamResponse.dispatch, } diff --git a/moto/kinesis/urls.py b/moto/kinesis/urls.py index e55bfcbef..5de870c29 100644 --- a/moto/kinesis/urls.py +++ b/moto/kinesis/urls.py @@ -6,5 +6,5 @@ url_bases = [ ] url_paths = { - '{0}/$': KinesisResponse().dispatch, + '{0}/$': KinesisResponse.dispatch, } diff --git a/moto/rds/urls.py b/moto/rds/urls.py index 0a7530c97..646f17304 100644 --- a/moto/rds/urls.py +++ b/moto/rds/urls.py @@ -6,5 +6,5 @@ url_bases = [ ] url_paths = { - '{0}/$': RDSResponse().dispatch, + '{0}/$': RDSResponse.dispatch, } diff --git a/moto/rds2/urls.py b/moto/rds2/urls.py index d21084766..d19dc2785 100644 --- a/moto/rds2/urls.py +++ b/moto/rds2/urls.py @@ -7,5 +7,5 @@ url_bases = [ ] url_paths = { - '{0}/$': RDS2Response().dispatch, + '{0}/$': RDS2Response.dispatch, } diff --git a/moto/redshift/urls.py b/moto/redshift/urls.py index 5d3ab296c..ebef59e86 100644 --- a/moto/redshift/urls.py +++ b/moto/redshift/urls.py @@ -6,5 +6,5 @@ url_bases = [ ] url_paths = { - '{0}/$': RedshiftResponse().dispatch, + '{0}/$': RedshiftResponse.dispatch, } diff --git a/moto/server.py b/moto/server.py index 2534f0d18..122803c82 100644 --- a/moto/server.py +++ b/moto/server.py @@ -74,7 +74,15 @@ def create_backend_app(service): backend = BACKENDS[service] for url_path, handler in backend.flask_paths.items(): - backend_app.route(url_path, methods=HTTP_METHODS)(convert_flask_to_httpretty_response(handler)) + if handler.__name__ == 'dispatch': + endpoint = '{}.dispatch'.format(handler.__self__.__name__) + else: + endpoint = None + + backend_app.route( + url_path, + endpoint=endpoint, + methods=HTTP_METHODS)(convert_flask_to_httpretty_response(handler)) return backend_app diff --git a/moto/ses/urls.py b/moto/ses/urls.py index 73db50a52..18d5874c4 100644 --- a/moto/ses/urls.py +++ b/moto/ses/urls.py @@ -6,5 +6,5 @@ url_bases = [ ] url_paths = { - '{0}/$': EmailResponse().dispatch, + '{0}/$': EmailResponse.dispatch, } diff --git a/moto/sns/urls.py b/moto/sns/urls.py index 8ed7cc234..769c0c89c 100644 --- a/moto/sns/urls.py +++ b/moto/sns/urls.py @@ -6,5 +6,5 @@ url_bases = [ ] url_paths = { - '{0}/$': SNSResponse().dispatch, + '{0}/$': SNSResponse.dispatch, } diff --git a/moto/sqs/urls.py b/moto/sqs/urls.py index ad973a3e4..527a867c2 100644 --- a/moto/sqs/urls.py +++ b/moto/sqs/urls.py @@ -6,6 +6,6 @@ url_bases = [ ] url_paths = { - '{0}/$': QueuesResponse().dispatch, - '{0}/(?P\d+)/(?P[a-zA-Z0-9\-_]+)': QueueResponse().dispatch, + '{0}/$': QueuesResponse.dispatch, + '{0}/(?P\d+)/(?P[a-zA-Z0-9\-_]+)': QueueResponse.dispatch, } diff --git a/moto/sts/urls.py b/moto/sts/urls.py index 0efe35979..c6e310960 100644 --- a/moto/sts/urls.py +++ b/moto/sts/urls.py @@ -6,5 +6,5 @@ url_bases = [ ] url_paths = { - '{0}/$': TokenResponse().dispatch, + '{0}/$': TokenResponse.dispatch, } From 5da5c571a950e59982cf9f15b42ac32452e7afe9 Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 20 May 2015 09:36:40 +0200 Subject: [PATCH 2/3] filtering the items is needed because of defaultdict is not threadsafe and returns an empty dict which results in an exception here --- moto/dynamodb2/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/moto/dynamodb2/models.py b/moto/dynamodb2/models.py index bc79b7e9a..f24d7398d 100644 --- a/moto/dynamodb2/models.py +++ b/moto/dynamodb2/models.py @@ -220,7 +220,7 @@ class Table(object): results = [] last_page = True # Once pagination is implemented, change this - possible_results = [item for item in list(self.all_items()) if item.hash_key == hash_key] + possible_results = [item for item in list(self.all_items()) if isinstance(item, Item) and item.hash_key == hash_key] if range_comparison: for result in possible_results: if result.range_key.compare(range_comparison, range_objs): From 450d14b4eb7b6afaeb6f2d073711080b5ab13d9e Mon Sep 17 00:00:00 2001 From: Jeffrey Gelens Date: Fri, 29 May 2015 11:43:24 +0200 Subject: [PATCH 3/3] Fix ValueError for Python 2.6 --- moto/server.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/moto/server.py b/moto/server.py index 122803c82..af3ec55bd 100644 --- a/moto/server.py +++ b/moto/server.py @@ -75,7 +75,7 @@ def create_backend_app(service): backend = BACKENDS[service] for url_path, handler in backend.flask_paths.items(): if handler.__name__ == 'dispatch': - endpoint = '{}.dispatch'.format(handler.__self__.__name__) + endpoint = '{0}.dispatch'.format(handler.__self__.__name__) else: endpoint = None