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'
|
__title__ = 'moto'
|
||||||
__version__ = '0.4.22'
|
__version__ = '0.4.22'
|
||||||
|
|
||||||
|
from .apigateway import mock_apigateway # flake8: noqa
|
||||||
from .autoscaling import mock_autoscaling # flake8: noqa
|
from .autoscaling import mock_autoscaling # flake8: noqa
|
||||||
from .awslambda import mock_lambda # flake8: noqa
|
from .awslambda import mock_lambda # flake8: noqa
|
||||||
from .cloudformation import mock_cloudformation # 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 __future__ import unicode_literals
|
||||||
|
from moto.apigateway import apigateway_backend
|
||||||
from moto.autoscaling import autoscaling_backend
|
from moto.autoscaling import autoscaling_backend
|
||||||
from moto.awslambda import lambda_backend
|
from moto.awslambda import lambda_backend
|
||||||
from moto.cloudwatch import cloudwatch_backend
|
from moto.cloudwatch import cloudwatch_backend
|
||||||
@ -23,6 +24,7 @@ from moto.sts import sts_backend
|
|||||||
from moto.route53 import route53_backend
|
from moto.route53 import route53_backend
|
||||||
|
|
||||||
BACKENDS = {
|
BACKENDS = {
|
||||||
|
'apigateway': apigateway_backend,
|
||||||
'autoscaling': autoscaling_backend,
|
'autoscaling': autoscaling_backend,
|
||||||
'cloudformation': cloudformation_backend,
|
'cloudformation': cloudformation_backend,
|
||||||
'cloudwatch': cloudwatch_backend,
|
'cloudwatch': cloudwatch_backend,
|
||||||
|
@ -94,9 +94,8 @@ class BaseResponse(_TemplateEnvironmentMixin):
|
|||||||
def dispatch(cls, *args, **kwargs):
|
def dispatch(cls, *args, **kwargs):
|
||||||
return cls()._dispatch(*args, **kwargs)
|
return cls()._dispatch(*args, **kwargs)
|
||||||
|
|
||||||
def _dispatch(self, request, full_url, headers):
|
def setup_class(self, request, full_url, headers):
|
||||||
querystring = {}
|
querystring = {}
|
||||||
|
|
||||||
if hasattr(request, 'body'):
|
if hasattr(request, 'body'):
|
||||||
# Boto
|
# Boto
|
||||||
self.body = request.body
|
self.body = request.body
|
||||||
@ -133,6 +132,9 @@ class BaseResponse(_TemplateEnvironmentMixin):
|
|||||||
|
|
||||||
self.headers = request.headers
|
self.headers = request.headers
|
||||||
self.response_headers = headers
|
self.response_headers = headers
|
||||||
|
|
||||||
|
def _dispatch(self, request, full_url, headers):
|
||||||
|
self.setup_class(request, full_url, headers)
|
||||||
return self.call_action()
|
return self.call_action()
|
||||||
|
|
||||||
def call_action(self):
|
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