base rest api endpoints.

This commit is contained in:
Steve Pulec 2016-03-01 12:03:59 -05:00
parent 2d471ecf9d
commit 45f92fb4c7
10 changed files with 208 additions and 2 deletions

View File

@ -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

View 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
View 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)

View 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
View 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
View 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))

View File

@ -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,

View File

@ -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):

View 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)

View 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": []}')