base rest api endpoints.
This commit is contained in:
parent
2d471ecf9d
commit
45f92fb4c7
@ -5,6 +5,7 @@ logging.getLogger('boto').setLevel(logging.CRITICAL)
|
||||
__title__ = 'moto'
|
||||
__version__ = '0.4.22'
|
||||
|
||||
from .apigateway import mock_apigateway # flake8: noqa
|
||||
from .autoscaling import mock_autoscaling # flake8: noqa
|
||||
from .awslambda import mock_lambda # flake8: noqa
|
||||
from .cloudformation import mock_cloudformation # flake8: noqa
|
||||
|
12
moto/apigateway/__init__.py
Normal file
12
moto/apigateway/__init__.py
Normal file
@ -0,0 +1,12 @@
|
||||
from __future__ import unicode_literals
|
||||
from .models import apigateway_backends
|
||||
from ..core.models import MockAWS
|
||||
|
||||
apigateway_backend = apigateway_backends['us-east-1']
|
||||
|
||||
|
||||
def mock_apigateway(func=None):
|
||||
if func:
|
||||
return MockAWS(apigateway_backends)(func)
|
||||
else:
|
||||
return MockAWS(apigateway_backends)
|
55
moto/apigateway/models.py
Normal file
55
moto/apigateway/models.py
Normal file
@ -0,0 +1,55 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import datetime
|
||||
from moto.core import BaseBackend
|
||||
from moto.core.utils import iso_8601_datetime_with_milliseconds
|
||||
from .utils import create_rest_api_id
|
||||
|
||||
|
||||
class RestAPI(object):
|
||||
def __init__(self, id, name, description):
|
||||
self.id = id
|
||||
self.name = name
|
||||
self.description = description
|
||||
self.create_date = datetime.datetime.utcnow()
|
||||
|
||||
def to_dict(self):
|
||||
return {
|
||||
"id": self.id,
|
||||
"name": self.name,
|
||||
"description": self.description,
|
||||
"createdDate": iso_8601_datetime_with_milliseconds(self.create_date),
|
||||
}
|
||||
|
||||
|
||||
class APIGatewayBackend(BaseBackend):
|
||||
def __init__(self, region_name):
|
||||
super(APIGatewayBackend, self).__init__()
|
||||
self.apis = {}
|
||||
self.region_name = region_name
|
||||
|
||||
def reset(self):
|
||||
region_name = self.region_name
|
||||
self.__dict__ = {}
|
||||
self.__init__(region_name)
|
||||
|
||||
def create_rest_api(self, name, description):
|
||||
api_id = create_rest_api_id()
|
||||
rest_api = RestAPI(api_id, name, description)
|
||||
self.apis[api_id] = rest_api
|
||||
return rest_api
|
||||
|
||||
def get_rest_api(self, function_id):
|
||||
rest_api = self.apis[function_id]
|
||||
return rest_api
|
||||
|
||||
def list_apis(self):
|
||||
return self.apis.values()
|
||||
|
||||
def delete_rest_api(self, function_id):
|
||||
rest_api = self.apis.pop(function_id)
|
||||
return rest_api
|
||||
|
||||
apigateway_backends = {}
|
||||
for region_name in ['us-east-1', 'us-west-2', 'eu-west-1', 'ap-northeast-1']: # Not available in boto yet
|
||||
apigateway_backends[region_name] = APIGatewayBackend(region_name)
|
40
moto/apigateway/responses.py
Normal file
40
moto/apigateway/responses.py
Normal file
@ -0,0 +1,40 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import json
|
||||
|
||||
from moto.core.responses import BaseResponse
|
||||
from .models import apigateway_backends
|
||||
|
||||
|
||||
class APIGatewayResponse(BaseResponse):
|
||||
|
||||
def _get_param(self, key):
|
||||
return json.loads(self.body).get(key)
|
||||
|
||||
@property
|
||||
def backend(self):
|
||||
return apigateway_backends[self.region]
|
||||
|
||||
def restapis(self, request, full_url, headers):
|
||||
self.setup_class(request, full_url, headers)
|
||||
|
||||
if self.method == 'GET':
|
||||
apis = self.backend.list_apis()
|
||||
return 200, headers, json.dumps({"item": [
|
||||
api.to_dict() for api in apis
|
||||
]})
|
||||
elif self.method == 'POST':
|
||||
name = self._get_param('name')
|
||||
description = self._get_param('description')
|
||||
rest_api = self.backend.create_rest_api(name, description)
|
||||
return 200, headers, json.dumps(rest_api.to_dict())
|
||||
|
||||
def restapis_individual(self, request, full_url, headers):
|
||||
self.setup_class(request, full_url, headers)
|
||||
function_id = self.path.split("/")[-1]
|
||||
if self.method == 'GET':
|
||||
rest_api = self.backend.get_rest_api(function_id)
|
||||
return 200, headers, json.dumps(rest_api.to_dict())
|
||||
elif self.method == 'DELETE':
|
||||
rest_api = self.backend.delete_rest_api(function_id)
|
||||
return 200, headers, json.dumps(rest_api.to_dict())
|
11
moto/apigateway/urls.py
Normal file
11
moto/apigateway/urls.py
Normal file
@ -0,0 +1,11 @@
|
||||
from __future__ import unicode_literals
|
||||
from .responses import APIGatewayResponse
|
||||
|
||||
url_bases = [
|
||||
"https?://apigateway.(.+).amazonaws.com"
|
||||
]
|
||||
|
||||
url_paths = {
|
||||
'{0}/restapis': APIGatewayResponse().restapis,
|
||||
'{0}/restapis/(?P<function_id>[^/]+)/?$': APIGatewayResponse().restapis_individual,
|
||||
}
|
9
moto/apigateway/utils.py
Normal file
9
moto/apigateway/utils.py
Normal file
@ -0,0 +1,9 @@
|
||||
from __future__ import unicode_literals
|
||||
import six
|
||||
import random
|
||||
|
||||
|
||||
def create_rest_api_id():
|
||||
size = 10
|
||||
chars = list(range(10)) + ['A-Z']
|
||||
return ''.join(six.text_type(random.choice(chars)) for x in range(size))
|
@ -1,4 +1,5 @@
|
||||
from __future__ import unicode_literals
|
||||
from moto.apigateway import apigateway_backend
|
||||
from moto.autoscaling import autoscaling_backend
|
||||
from moto.awslambda import lambda_backend
|
||||
from moto.cloudwatch import cloudwatch_backend
|
||||
@ -23,6 +24,7 @@ from moto.sts import sts_backend
|
||||
from moto.route53 import route53_backend
|
||||
|
||||
BACKENDS = {
|
||||
'apigateway': apigateway_backend,
|
||||
'autoscaling': autoscaling_backend,
|
||||
'cloudformation': cloudformation_backend,
|
||||
'cloudwatch': cloudwatch_backend,
|
||||
|
@ -94,9 +94,8 @@ class BaseResponse(_TemplateEnvironmentMixin):
|
||||
def dispatch(cls, *args, **kwargs):
|
||||
return cls()._dispatch(*args, **kwargs)
|
||||
|
||||
def _dispatch(self, request, full_url, headers):
|
||||
def setup_class(self, request, full_url, headers):
|
||||
querystring = {}
|
||||
|
||||
if hasattr(request, 'body'):
|
||||
# Boto
|
||||
self.body = request.body
|
||||
@ -133,6 +132,9 @@ class BaseResponse(_TemplateEnvironmentMixin):
|
||||
|
||||
self.headers = request.headers
|
||||
self.response_headers = headers
|
||||
|
||||
def _dispatch(self, request, full_url, headers):
|
||||
self.setup_class(request, full_url, headers)
|
||||
return self.call_action()
|
||||
|
||||
def call_action(self):
|
||||
|
58
tests/test_apigateway/test_apigateway.py
Normal file
58
tests/test_apigateway/test_apigateway.py
Normal file
@ -0,0 +1,58 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from datetime import datetime
|
||||
from dateutil.tz import tzutc
|
||||
import boto3
|
||||
from freezegun import freeze_time
|
||||
import sure # noqa
|
||||
|
||||
from moto import mock_apigateway
|
||||
|
||||
|
||||
@freeze_time("2015-01-01")
|
||||
@mock_apigateway
|
||||
def test_create_and_get_rest_api():
|
||||
client = boto3.client('apigateway', region_name='us-west-2')
|
||||
|
||||
response = client.create_rest_api(
|
||||
name='my_api',
|
||||
description='this is my api',
|
||||
)
|
||||
api_id = response['id']
|
||||
|
||||
response = client.get_rest_api(
|
||||
restApiId=api_id
|
||||
)
|
||||
|
||||
response.pop('ResponseMetadata')
|
||||
response.should.equal({
|
||||
'id': api_id,
|
||||
'name': 'my_api',
|
||||
'description': 'this is my api',
|
||||
'createdDate': datetime(2015, 1, 1, tzinfo=tzutc())
|
||||
})
|
||||
|
||||
|
||||
@mock_apigateway
|
||||
def test_list_and_delete_apis():
|
||||
client = boto3.client('apigateway', region_name='us-west-2')
|
||||
|
||||
response = client.create_rest_api(
|
||||
name='my_api',
|
||||
description='this is my api',
|
||||
)
|
||||
api_id = response['id']
|
||||
client.create_rest_api(
|
||||
name='my_api2',
|
||||
description='this is my api2',
|
||||
)
|
||||
|
||||
response = client.get_rest_apis()
|
||||
len(response['items']).should.equal(2)
|
||||
|
||||
client.delete_rest_api(
|
||||
restApiId=api_id
|
||||
)
|
||||
|
||||
response = client.get_rest_apis()
|
||||
len(response['items']).should.equal(1)
|
16
tests/test_apigateway/test_server.py
Normal file
16
tests/test_apigateway/test_server.py
Normal file
@ -0,0 +1,16 @@
|
||||
from __future__ import unicode_literals
|
||||
import sure # noqa
|
||||
|
||||
import moto.server as server
|
||||
|
||||
'''
|
||||
Test the different server responses
|
||||
'''
|
||||
|
||||
|
||||
def test_list_apis():
|
||||
backend = server.create_backend_app("apigateway")
|
||||
test_client = backend.test_client()
|
||||
|
||||
res = test_client.get('/restapis')
|
||||
res.data.should.equal(b'{"item": []}')
|
Loading…
x
Reference in New Issue
Block a user