Adding logging, new cookiecutter params for cors and static report, changed factory function

master
androiddrew 6 years ago
parent ae2f1c696c
commit 7458224fa1

5
.gitignore vendored

@ -59,4 +59,7 @@ docs/_build/
target/ target/
# Pycharm # Pycharm
.idea .idea
# Mac
.DS_Store

@ -5,5 +5,7 @@
"project_name": "molten-app", "project_name": "molten-app",
"project_slug": "{{ cookiecutter.project_name.lower().strip().replace(' ', '_').replace('-','_')}}", "project_slug": "{{ cookiecutter.project_name.lower().strip().replace(' ', '_').replace('-','_')}}",
"description": "An molten project templated by cookiecutter-molten", "description": "An molten project templated by cookiecutter-molten",
"cors_support": "n",
"static_support": "n",
"open_source_license": ["MIT license", "BSD license", "ISC license", "Apache Software License 2.0", "GNU General Public License v3", "Not open source"] "open_source_license": ["MIT license", "BSD license", "ISC license", "Apache Software License 2.0", "GNU General Public License v3", "Not open source"]
} }

@ -0,0 +1,2 @@
[alembic]
script_location = migrations

@ -1,28 +0,0 @@
#
# This file is autogenerated by pip-compile
# To update, run:
#
# pip-compile --output-file dev_requirements.txt dev_requirements.in
#
--trusted-host pypi.python.org
appdirs==1.4.3 # via black
atomicwrites==1.2.1 # via pytest
attrs==18.2.0 # via black, pytest
black==18.9b0
bumpversion==0.5.3
click==7.0 # via black, pip-tools
coverage==4.5.2 # via pytest-cov
flake8==3.6.0
mccabe==0.6.1 # via flake8
more-itertools==4.3.0 # via pytest
pip-tools==3.1.0
pluggy==0.8.0 # via pytest
py==1.7.0 # via pytest
pycodestyle==2.4.0 # via flake8
pyflakes==2.0.0 # via flake8
pytest-cov==2.6.0
pytest==4.0.1
six==1.11.0 # via more-itertools, pip-tools, pytest
toml==0.10.0 # via black
werkzeug==0.14.1

@ -2,7 +2,7 @@ import click
from molten.contrib.sqlalchemy import EngineData from molten.contrib.sqlalchemy import EngineData
from {{cookiecutter.project_slug}}.index import create_app from {{cookiecutter.project_slug}}.index import create_app
app = create_app() _, app = create_app()
@click.group() @click.group()

@ -1,4 +1,11 @@
click click
molten molten
sqlalchemy sqlalchemy
psycopg2-binary psycopg2-binary
alembic
{% if cookiecutter.cors_support == 'y' %}
wisgcors
{% endif %}
{% if cookiecutter.static_support == 'y' %}
whitenoise
{% endif %}

@ -1,15 +0,0 @@
#
# This file is autogenerated by pip-compile
# To update, run:
#
# pip-compile --output-file requirements.txt requirements.in
#
--trusted-host pypi.python.org
click==7.0
molten==0.7.3
mypy-extensions==0.4.1 # via typing-inspect
psycopg2-binary==2.7.6.1
sqlalchemy==1.2.14
typing-extensions==3.6.6 # via molten
typing-inspect==0.3.1 # via molten

@ -0,0 +1,15 @@
#!/usr/bin/env bash
# setting -e to exit immediately on a command failure.
# setting -o pipefail sets the exit code of a pipeline to that of the rightmost command to exit with a non-zero status, or to zero if all commands of the pipeline exit successfully.
set -eo pipefail
if [ -z "$VIRTUAL_ENV" ]; then
echo "warning: you are not in a virtualenv"
exit 1
fi
pip install -U pip pip-tools
pip-compile requirements.in
pip-compile dev_requirements.in
pip-sync requirements.txt dev_requirements.txt

@ -11,7 +11,7 @@ from {{cookiecutter.project_slug}}.db import Base
# requires function scope so that database is removed on every tests # requires function scope so that database is removed on every tests
@pytest.fixture(scope="function") @pytest.fixture(scope="function")
def app(): def app():
app = create_app() _, app = create_app()
yield app yield app

@ -5,10 +5,17 @@ from molten.http import HTTP_404, Request
from molten.openapi import Metadata, OpenAPIHandler, OpenAPIUIHandler from molten.openapi import Metadata, OpenAPIHandler, OpenAPIUIHandler
from molten.settings import SettingsComponent from molten.settings import SettingsComponent
from molten.contrib.sqlalchemy import SQLAlchemyMiddleware, SQLAlchemyEngineComponent, SQLAlchemySessionComponent from molten.contrib.sqlalchemy import SQLAlchemyMiddleware, SQLAlchemyEngineComponent, SQLAlchemySessionComponent
{ % if cookiecutter.cors_support == 'y' %}
from wsgicors import CORS
{ % endif %}
{ % if cookiecutter.cors_support == 'y' %}
from whitenoise import WhiteNoise
{ % endif %}
from .api.welcome import welcome from .api.welcome import welcome
from .api.todo import TodoManagerComponent, todo_routes from .api.todo import TodoManagerComponent, todo_routes
from .common import ExtJSONRenderer from .common import ExtJSONRenderer
from .logging import setup_logging
from .schema import APIResponse from .schema import APIResponse
from .settings import SETTINGS from .settings import SETTINGS
@ -64,12 +71,23 @@ class ExtApp(App):
def create_app(_components=None, _middleware=None, _routes=None, _renderers=None): def create_app(_components=None, _middleware=None, _routes=None, _renderers=None):
""" """
Factory function for the creation of a `molten.App` instance Factory function for the creation of a `molten.App`.
""" """
app = ExtApp( setup_logging()
wrapped_app = app = ExtApp(
components=_components or components, components=_components or components,
middleware=_middleware or middleware, middleware=_middleware or middleware,
routes=_routes or routes, routes=_routes or routes,
renderers=_renderers or renderers renderers=_renderers or renderers
) )
return app
{ % if cookiecutter.cors_support == 'y' %}
wrapped_app = CORS(wrapped_app, **settings.strict_get("wsgicors"))
{ % endif %}
{ % if cookiecutter.static_support == 'y' %}
wrapped_app = WhiteNoise(wrapped_app, **settings.strict_get("whitenoise"))
{ % endif %}
return wrapped_app, app

@ -0,0 +1,29 @@
import logging.config
import sys
FORMAT = "[%(asctime)s] [PID %(process)d] [%(threadName)s] [%(request_id)s] [%(name)s] [%(levelname)s] %(message)s" # noqa
def setup_logging():
logging.config.dictConfig(
{
"disable_existing_loggers": False,
"version": 1,
"filters": {
"request_id": {"()": "molten.contrib.request_id.RequestIdFilter"}
},
"formatters": {"console": {"format": FORMAT}},
"handlers": {
"default": {
"level": "DEBUG",
"class": "logging.StreamHandler",
"stream": sys.stderr,
"formatter": "console",
"filters": ["request_id"],
}
},
"loggers": {
"": {"handlers": ["default"], "level": "DEBUG", "propagate": False}
},
}
)

@ -0,0 +1,21 @@
"""isort:skip_file
"""
import os
import sys; sys.path.append(os.path.join(os.path.abspath(os.path.dirname(__file__)), "..")) # noqa
from alembic import context
from {{cookiecutter.package_name}}.index import create_app
from {{cookiecutter.package_name}}.db import Base
from molten.contrib.sqlalchemy import EngineData
_, app = create_app()
def run_migrations_online(engine_data: EngineData):
with engine_data.engine.connect() as connection:
context.configure(connection=connection, target_metadata=Base.metadata)
with context.begin_transaction():
context.run_migrations()
app.injector.get_resolver().resolve(run_migrations_online)()

@ -1,10 +1,26 @@
[common] [common]
database_engine_dsn = "postgresql://molten:local@localhost/cookiecutter" database_engine_dsn = "postgresql://molten:local@localhost/cookiecutter"
[common.wsgicors]
headers="*"
methods="*"
maxage="180"
origin="*"
[common.whitenoise]
root = "static"
prefix = "/static"
autorefresh = true
[dev] [dev]
database_engine_params.echo = true database_engine_params.echo = true
database_engine_params.connect_args.options = "-c timezone=utc" database_engine_params.connect_args.options = "-c timezone=utc"
[test] [test]
database_engine_dsn = "postgresql://molten:local@localhost/test_cookiecutter" database_engine_dsn = "postgresql://molten:local@localhost/test_cookiecutter"
database_engine_params.echo = true database_engine_params.echo = true
[prod.whitenoise]
root = "static"
prefix = "/static"
autorefresh = false
Loading…
Cancel
Save