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 336cade3..0743fdcf 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 f2cfb020..468c68d9 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 2371f09c..0a9101cf 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 a99ac78c..bd54cf01 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 1afd3435..66c15d02 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 1afd3435..66c15d02 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 e2768908..768a8cd3 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 ee7703ff..48fcb37a 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 0daa41e0..83eb62b2 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 8c05a6f0..a591e3eb 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 e55bfcbe..5de870c2 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 0a7530c9..646f1730 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 d2108476..d19dc278 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 5d3ab296..ebef59e8 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 2534f0d1..122803c8 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 73db50a5..18d5874c 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 8ed7cc23..769c0c89 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 ad973a3e..527a867c 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 0efe3597..c6e31096 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 bc79b7e9..f24d7398 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 122803c8..af3ec55b 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