First version of dashboard.

This commit is contained in:
Steve Pulec 2017-03-11 22:45:42 -05:00
commit 1709208872
9 changed files with 249 additions and 7 deletions

View file

@ -1,9 +1,11 @@
from __future__ import unicode_literals
from __future__ import absolute_import
from collections import defaultdict
import functools
import inspect
import re
import six
from moto import settings
from moto.packages.responses import responses
@ -208,12 +210,38 @@ class Model(type):
return dec
model_data = defaultdict(dict)
class InstanceTrackerMeta(type):
def __new__(meta, name, bases, dct):
cls = super(InstanceTrackerMeta, meta).__new__(meta, name, bases, dct)
if name == 'BaseModel':
return cls
service = cls.__module__.split(".")[1]
if name not in model_data[service]:
model_data[service][name] = cls
cls.instances = []
return cls
@six.add_metaclass(InstanceTrackerMeta)
class BaseModel(object):
def __new__(cls, *args, **kwargs):
instance = super(BaseModel, cls).__new__(cls, *args, **kwargs)
cls.instances.append(instance)
return instance
class BaseBackend(object):
def reset(self):
self.__dict__ = {}
self.__init__()
def get_models(self):
import pdb;pdb.set_trace()
models = getattr(backend.__class__, '__models__', {})
@property
def _url_module(self):
backend_module = self.__class__.__module__

View file

@ -12,6 +12,7 @@ from jinja2 import Environment, DictLoader, TemplateNotFound
import six
from six.moves.urllib.parse import parse_qs, urlparse
from flask import render_template
import xmltodict
from pkg_resources import resource_filename
from werkzeug.exceptions import HTTPException
@ -350,6 +351,32 @@ class MotoAPIResponse(BaseResponse):
return 200, {}, json.dumps({"status": "ok"})
return 400, {}, json.dumps({"Error": "Need to POST to reset Moto"})
def model_data(self, request, full_url, headers):
from moto.core.models import model_data
results = {}
for service in sorted(model_data):
models = model_data[service]
results[service] = {}
for name in sorted(models):
model = models[name]
results[service][name] = []
for instance in model.instances:
inst_result = {}
for attr in dir(instance):
if not attr.startswith("_"):
try:
json.dumps(getattr(instance, attr))
except TypeError:
pass
else:
inst_result[attr] = getattr(instance, attr)
results[service][name].append(inst_result)
return 200, {"Content-Type": "application/javascript"}, json.dumps(results)
def dashboard(self, request, full_url, headers):
return render_template('dashboard.html')
class _RecursiveDictRef(object):
"""Store a recursive reference to dict."""

View file

@ -8,5 +8,7 @@ url_bases = [
response_instance = MotoAPIResponse()
url_paths = {
'{0}/moto-api/$': response_instance.dashboard,
'{0}/moto-api/data.json': response_instance.model_data,
'{0}/moto-api/reset': response_instance.reset_response,
}

View file

@ -122,7 +122,10 @@ class convert_flask_to_httpretty_response(object):
result = self.callback(request, request.url, {})
# result is a status, headers, response tuple
status, headers, content = result
if len(result) == 3:
status, headers, content = result
else:
status, headers, content = 200, {}, result
response = Response(response=content, status=status, headers=headers)
if request.method == "HEAD" and 'content-length' in headers: