From 7458224fa14e34cddd207c141333587237c53067 Mon Sep 17 00:00:00 2001 From: androiddrew Date: Sat, 26 Jan 2019 17:54:34 -0500 Subject: [PATCH] Adding logging, new cookiecutter params for cors and static report, changed factory function --- .gitignore | 5 +++- cookiecutter.json | 2 ++ {{cookiecutter.project_slug}}/alembic.ini | 2 ++ .../dev_requirements.txt | 28 ------------------ {{cookiecutter.project_slug}}/manage.py | 2 +- {{cookiecutter.project_slug}}/requirements.in | 9 +++++- .../requirements.txt | 15 ---------- .../scripts/bootstrap | 15 ++++++++++ .../tests/conftest.py | 2 +- .../{{cookiecutter.project_slug}}/index.py | 24 +++++++++++++-- .../{{cookiecutter.project_slug}}/logging.py | 29 +++++++++++++++++++ .../migrations/env.py | 21 ++++++++++++++ .../settings.toml | 18 +++++++++++- 13 files changed, 121 insertions(+), 51 deletions(-) create mode 100644 {{cookiecutter.project_slug}}/alembic.ini delete mode 100644 {{cookiecutter.project_slug}}/dev_requirements.txt delete mode 100644 {{cookiecutter.project_slug}}/requirements.txt create mode 100755 {{cookiecutter.project_slug}}/scripts/bootstrap create mode 100644 {{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/logging.py create mode 100644 {{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/migrations/env.py diff --git a/.gitignore b/.gitignore index 31496a5..6b0c651 100644 --- a/.gitignore +++ b/.gitignore @@ -59,4 +59,7 @@ docs/_build/ target/ # Pycharm -.idea \ No newline at end of file +.idea + +# Mac +.DS_Store \ No newline at end of file diff --git a/cookiecutter.json b/cookiecutter.json index 6970bfd..4149f80 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -5,5 +5,7 @@ "project_name": "molten-app", "project_slug": "{{ cookiecutter.project_name.lower().strip().replace(' ', '_').replace('-','_')}}", "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"] } \ No newline at end of file diff --git a/{{cookiecutter.project_slug}}/alembic.ini b/{{cookiecutter.project_slug}}/alembic.ini new file mode 100644 index 0000000..2c614a3 --- /dev/null +++ b/{{cookiecutter.project_slug}}/alembic.ini @@ -0,0 +1,2 @@ +[alembic] +script_location = migrations \ No newline at end of file diff --git a/{{cookiecutter.project_slug}}/dev_requirements.txt b/{{cookiecutter.project_slug}}/dev_requirements.txt deleted file mode 100644 index 178b283..0000000 --- a/{{cookiecutter.project_slug}}/dev_requirements.txt +++ /dev/null @@ -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 diff --git a/{{cookiecutter.project_slug}}/manage.py b/{{cookiecutter.project_slug}}/manage.py index fff14da..1ed25e6 100644 --- a/{{cookiecutter.project_slug}}/manage.py +++ b/{{cookiecutter.project_slug}}/manage.py @@ -2,7 +2,7 @@ import click from molten.contrib.sqlalchemy import EngineData from {{cookiecutter.project_slug}}.index import create_app -app = create_app() +_, app = create_app() @click.group() diff --git a/{{cookiecutter.project_slug}}/requirements.in b/{{cookiecutter.project_slug}}/requirements.in index 21c792d..f209c34 100644 --- a/{{cookiecutter.project_slug}}/requirements.in +++ b/{{cookiecutter.project_slug}}/requirements.in @@ -1,4 +1,11 @@ click molten sqlalchemy -psycopg2-binary \ No newline at end of file +psycopg2-binary +alembic +{% if cookiecutter.cors_support == 'y' %} +wisgcors +{% endif %} +{% if cookiecutter.static_support == 'y' %} +whitenoise +{% endif %} \ No newline at end of file diff --git a/{{cookiecutter.project_slug}}/requirements.txt b/{{cookiecutter.project_slug}}/requirements.txt deleted file mode 100644 index a3d39f3..0000000 --- a/{{cookiecutter.project_slug}}/requirements.txt +++ /dev/null @@ -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 diff --git a/{{cookiecutter.project_slug}}/scripts/bootstrap b/{{cookiecutter.project_slug}}/scripts/bootstrap new file mode 100755 index 0000000..38e8a67 --- /dev/null +++ b/{{cookiecutter.project_slug}}/scripts/bootstrap @@ -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 diff --git a/{{cookiecutter.project_slug}}/tests/conftest.py b/{{cookiecutter.project_slug}}/tests/conftest.py index 495394e..76f256e 100644 --- a/{{cookiecutter.project_slug}}/tests/conftest.py +++ b/{{cookiecutter.project_slug}}/tests/conftest.py @@ -11,7 +11,7 @@ from {{cookiecutter.project_slug}}.db import Base # requires function scope so that database is removed on every tests @pytest.fixture(scope="function") def app(): - app = create_app() + _, app = create_app() yield app diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/index.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/index.py index e3e60fb..2d82631 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/index.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/index.py @@ -5,10 +5,17 @@ from molten.http import HTTP_404, Request from molten.openapi import Metadata, OpenAPIHandler, OpenAPIUIHandler from molten.settings import SettingsComponent 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.todo import TodoManagerComponent, todo_routes from .common import ExtJSONRenderer +from .logging import setup_logging from .schema import APIResponse from .settings import SETTINGS @@ -64,12 +71,23 @@ class ExtApp(App): 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, middleware=_middleware or middleware, routes=_routes or routes, 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 diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/logging.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/logging.py new file mode 100644 index 0000000..fb36de8 --- /dev/null +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/logging.py @@ -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} + }, + } + ) diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/migrations/env.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/migrations/env.py new file mode 100644 index 0000000..2726330 --- /dev/null +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/migrations/env.py @@ -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)() \ No newline at end of file diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/settings.toml b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/settings.toml index e42cc8e..01723ff 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/settings.toml +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/settings.toml @@ -1,10 +1,26 @@ [common] database_engine_dsn = "postgresql://molten:local@localhost/cookiecutter" +[common.wsgicors] +headers="*" +methods="*" +maxage="180" +origin="*" + +[common.whitenoise] +root = "static" +prefix = "/static" +autorefresh = true + [dev] database_engine_params.echo = true database_engine_params.connect_args.options = "-c timezone=utc" [test] database_engine_dsn = "postgresql://molten:local@localhost/test_cookiecutter" -database_engine_params.echo = true \ No newline at end of file +database_engine_params.echo = true + +[prod.whitenoise] +root = "static" +prefix = "/static" +autorefresh = false \ No newline at end of file