From d9a3d38602c318f77ced5fe807b1671936e179e8 Mon Sep 17 00:00:00 2001 From: Mathieu Imfeld Date: Sat, 12 Mar 2022 15:07:32 +0100 Subject: [PATCH 1/5] Cosmetics --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e33ea1e..4d607ad 100644 --- a/README.md +++ b/README.md @@ -355,4 +355,4 @@ following form. The DISCOVERY_URL must point to the URL where the IdP publishes } ``` ->The client requires configuration with OIDC secrets and currently implements the Device code flow +>The client requires configuration with OIDC secrets and currently implements the Device code flow From bb66001f3e3183dd1a51d29411523ffb24e9e308 Mon Sep 17 00:00:00 2001 From: Mathieu Imfeld Date: Sat, 30 Apr 2022 11:10:56 +0200 Subject: [PATCH 2/5] We're lenient on module docstrings --- .pylintrc | 1 + 1 file changed, 1 insertion(+) diff --git a/.pylintrc b/.pylintrc index d735031..fd140d3 100644 --- a/.pylintrc +++ b/.pylintrc @@ -90,6 +90,7 @@ disable=abstract-method, map-builtin-not-iterating, misplaced-comparison-constant, missing-function-docstring, + missing-module-docstring, metaclass-assignment, next-method-called, next-method-defined, From 63107175aba091c06e8a4806d5593f8ada2b5b14 Mon Sep 17 00:00:00 2001 From: Mathieu Imfeld Date: Sat, 30 Apr 2022 11:20:14 +0200 Subject: [PATCH 3/5] Cosmetic change --- mrmat_python_api_flask/apis/resource/v1/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mrmat_python_api_flask/apis/resource/v1/api.py b/mrmat_python_api_flask/apis/resource/v1/api.py index 5ef6ef7..35f231b 100644 --- a/mrmat_python_api_flask/apis/resource/v1/api.py +++ b/mrmat_python_api_flask/apis/resource/v1/api.py @@ -58,7 +58,7 @@ def get_all(): @bp.route('/', methods=['GET']) @bp.doc(summary='Get a single resource', - description='Return a single resource identified by its resource id.', + description='Return a single resource identified by its resource id', security=[{'openId': ['mpaf-read']}]) @bp.response(200, schema=ResourceSchema) @oidc.accept_token(require_token=True, scopes_required=['mpaf-read']) From 27029a4b66442d298cd32903524690dacb9cf339 Mon Sep 17 00:00:00 2001 From: Mr Mat Date: Mon, 1 Aug 2022 13:27:19 +0200 Subject: [PATCH 4/5] Small updates (#22) * Applied source layout * Added lint configuration * Fixed IDEA pylint configuration * Adjusted path * Adjusted path for pytest * Upgraded dependencies --- .github/workflows/build.yml | 4 +-- .idea/mrmat-python-api-flask.iml | 2 +- .idea/pylint.xml | 1 - .idea/runConfigurations/docker__nostromo_.xml | 30 ------------------- .idea/runConfigurations/lint.xml | 24 +++++++++++++++ ...ython_api_flask__local_infrastructure_.xml | 2 ++ ...t_python_api_flask__no_infrastructure_.xml | 4 +++ ...n_api_flask__no_infrastructure__debug_.xml | 5 ++++ README.md | 4 +-- requirements.txt | 16 +++++----- setup.cfg | 8 +++++ .../mrmat_python_api_flask}/__init__.py | 6 ++-- .../mrmat_python_api_flask}/apis/__init__.py | 0 .../apis/greeting/__init__.py | 0 .../apis/greeting/v1/__init__.py | 0 .../apis/greeting/v1/api.py | 0 .../apis/greeting/v1/model.py | 0 .../apis/greeting/v2/__init__.py | 0 .../apis/greeting/v2/api.py | 0 .../apis/greeting/v2/model.py | 0 .../apis/greeting/v3/__init__.py | 0 .../apis/greeting/v3/api.py | 0 .../apis/greeting/v3/model.py | 0 .../apis/healthz/__init__.py | 0 .../apis/healthz/api.py | 0 .../apis/resource/__init__.py | 0 .../apis/resource/v1/__init__.py | 0 .../apis/resource/v1/api.py | 0 .../apis/resource/v1/model.py | 0 .../python/mrmat_python_api_flask}/client.py | 0 .../python/mrmat_python_api_flask}/cui.py | 0 .../mrmat_python_api_flask/migrations}/README | 0 .../migrations}/alembic.ini | 0 .../mrmat_python_api_flask/migrations}/env.py | 0 .../migrations}/script.py.mako | 0 .../versions/2c4268119c7e_initial.py | 0 .../templates/swagger-ui-redirect.html | 0 tests/conftest.py | 7 ++++- 38 files changed, 65 insertions(+), 48 deletions(-) delete mode 100644 .idea/runConfigurations/docker__nostromo_.xml create mode 100644 .idea/runConfigurations/lint.xml rename {mrmat_python_api_flask => src/python/mrmat_python_api_flask}/__init__.py (97%) rename {mrmat_python_api_flask => src/python/mrmat_python_api_flask}/apis/__init__.py (100%) rename {mrmat_python_api_flask => src/python/mrmat_python_api_flask}/apis/greeting/__init__.py (100%) rename {mrmat_python_api_flask => src/python/mrmat_python_api_flask}/apis/greeting/v1/__init__.py (100%) rename {mrmat_python_api_flask => src/python/mrmat_python_api_flask}/apis/greeting/v1/api.py (100%) rename {mrmat_python_api_flask => src/python/mrmat_python_api_flask}/apis/greeting/v1/model.py (100%) rename {mrmat_python_api_flask => src/python/mrmat_python_api_flask}/apis/greeting/v2/__init__.py (100%) rename {mrmat_python_api_flask => src/python/mrmat_python_api_flask}/apis/greeting/v2/api.py (100%) rename {mrmat_python_api_flask => src/python/mrmat_python_api_flask}/apis/greeting/v2/model.py (100%) rename {mrmat_python_api_flask => src/python/mrmat_python_api_flask}/apis/greeting/v3/__init__.py (100%) rename {mrmat_python_api_flask => src/python/mrmat_python_api_flask}/apis/greeting/v3/api.py (100%) rename {mrmat_python_api_flask => src/python/mrmat_python_api_flask}/apis/greeting/v3/model.py (100%) rename {mrmat_python_api_flask => src/python/mrmat_python_api_flask}/apis/healthz/__init__.py (100%) rename {mrmat_python_api_flask => src/python/mrmat_python_api_flask}/apis/healthz/api.py (100%) rename {mrmat_python_api_flask => src/python/mrmat_python_api_flask}/apis/resource/__init__.py (100%) rename {mrmat_python_api_flask => src/python/mrmat_python_api_flask}/apis/resource/v1/__init__.py (100%) rename {mrmat_python_api_flask => src/python/mrmat_python_api_flask}/apis/resource/v1/api.py (100%) rename {mrmat_python_api_flask => src/python/mrmat_python_api_flask}/apis/resource/v1/model.py (100%) rename {mrmat_python_api_flask => src/python/mrmat_python_api_flask}/client.py (100%) rename {mrmat_python_api_flask => src/python/mrmat_python_api_flask}/cui.py (100%) rename {migrations => src/python/mrmat_python_api_flask/migrations}/README (100%) rename {migrations => src/python/mrmat_python_api_flask/migrations}/alembic.ini (100%) rename {migrations => src/python/mrmat_python_api_flask/migrations}/env.py (100%) rename {migrations => src/python/mrmat_python_api_flask/migrations}/script.py.mako (100%) rename {migrations => src/python/mrmat_python_api_flask/migrations}/versions/2c4268119c7e_initial.py (100%) rename {mrmat_python_api_flask => src/python/mrmat_python_api_flask}/templates/swagger-ui-redirect.html (100%) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 070bcec..da276fc 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -72,8 +72,8 @@ jobs: export PYTHONUSERBASE=${HOME}/.local pip install --user wheel pip install --user -r requirements.txt - ${PYTHONUSERBASE}/bin/pylint ${GITHUB_WORKSPACE}/mrmat_python_api_flask - PYTHONPATH=${GITHUB_WORKSPACE} python -m pytest --cov=mrmat_python_api_flask + ${PYTHONUSERBASE}/bin/pylint ${GITHUB_WORKSPACE}/src/python/mrmat_python_api_flask + PYTHONPATH=${GITHUB_WORKSPACE}/src/python python -m pytest --cov=mrmat_python_api_flask PYTHONPATH=${GITHUB_WORKSPACE} python -m build --wheel -n - name: Upload test results diff --git a/.idea/mrmat-python-api-flask.iml b/.idea/mrmat-python-api-flask.iml index 6334ba1..510d78f 100644 --- a/.idea/mrmat-python-api-flask.iml +++ b/.idea/mrmat-python-api-flask.iml @@ -6,7 +6,7 @@ - + diff --git a/.idea/pylint.xml b/.idea/pylint.xml index 161503e..46ea4e7 100644 --- a/.idea/pylint.xml +++ b/.idea/pylint.xml @@ -1,7 +1,6 @@ - \ No newline at end of file diff --git a/.idea/runConfigurations/docker__nostromo_.xml b/.idea/runConfigurations/docker__nostromo_.xml deleted file mode 100644 index 94c0d6f..0000000 --- a/.idea/runConfigurations/docker__nostromo_.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/lint.xml b/.idea/runConfigurations/lint.xml new file mode 100644 index 0000000..ed038d7 --- /dev/null +++ b/.idea/runConfigurations/lint.xml @@ -0,0 +1,24 @@ + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/mrmat_python_api_flask__local_infrastructure_.xml b/.idea/runConfigurations/mrmat_python_api_flask__local_infrastructure_.xml index 7cbd771..74625bb 100644 --- a/.idea/runConfigurations/mrmat_python_api_flask__local_infrastructure_.xml +++ b/.idea/runConfigurations/mrmat_python_api_flask__local_infrastructure_.xml @@ -8,7 +8,9 @@ - + diff --git a/.pylintrc b/.pylintrc index fd140d3..89e53ac 100644 --- a/.pylintrc +++ b/.pylintrc @@ -90,7 +90,6 @@ disable=abstract-method, map-builtin-not-iterating, misplaced-comparison-constant, missing-function-docstring, - missing-module-docstring, metaclass-assignment, next-method-called, next-method-defined, @@ -147,6 +146,7 @@ disable=abstract-method, wrong-import-order, xrange-builtin, zip-builtin-not-iterating, + missing-module-docstring [REPORTS] @@ -156,12 +156,6 @@ disable=abstract-method, # mypackage.mymodule.MyReporterClass. output-format=text -# Put messages in a separate file for each module / package specified on the -# command line instead of printing them on stdout. Reports (if any) will be -# written in a file name "pylint_global.[txt|html]". This option is deprecated -# and it will be removed in Pylint 2.0. -files-output=no - # Tells whether to display a full report or only the messages reports=no @@ -280,12 +274,6 @@ ignore-long-lines=(?x)( # else. single-line-if-stmt=yes -# List of optional constructs for which whitespace checking is disabled. `dict- -# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}. -# `trailing-comma` allows a space between comma and closing bracket: (a, ). -# `empty-line` allows space-only lines. -no-space-check= - # Maximum number of lines in a module max-module-lines=99999 diff --git a/LICENSE b/LICENSE index 24158cc..263a877 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021 MrMatOrg +Copyright (c) 2021 Mathieu Imfeld Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 877ed7d..0000000 --- a/MANIFEST.in +++ /dev/null @@ -1,5 +0,0 @@ -# -# If and when we have templates or static content, graft it here -#graft mrmat_python_api_flask/templates -#graft mrmat_python_api_flask/static -global-exclude *.pyc diff --git a/README.md b/README.md index 7e60e01..3891936 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # MrMat :: Python :: API :: Flask -[![Build](https://github.com/MrMatOrg/mrmat-python-api-flask/actions/workflows/build.yml/badge.svg)](https://github.com/MrMatOrg/mrmat-python-api-flask/actions/workflows/build.yml) +[![Build](https://github.com/MrMatAP/mrmat-python-api-flask/actions/workflows/build.yml/badge.svg)](https://github.com/MrMatAP/mrmat-python-api-flask/actions/workflows/build.yml) Boilerplate (and playground) for a code-first Python Flask API, with all the bells and whistles we've come to expect: diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..edfa253 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,13 @@ +# Security Policy + +## Supported Versions + +I'd be surprised if you'd want support for this. But be my guest raising an issue... + +| Version | Supported | +| ------- | ------------------ | +| all | :white_check_mark: | + +## Reporting a Vulnerability + +Raise an issue straight on this repository. diff --git a/pyproject.toml b/pyproject.toml index 7e01ab2..c7ad76f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,3 +1,70 @@ [build-system] -requires = ['setuptools', 'wheel'] +requires = [ + 'setuptools>=42.0.0', + 'wheel >= 0.36.0', + 'pylint~=2.15.5', # MIT + 'pytest~=7.2.0', # GPL-2.0-or-later + 'pytest-cov~=4.0.0', # MIT + 'pyjwt~=2.6.0', # MIT + 'python-keycloak~=2.6.0' # MIT +] build-backend = 'setuptools.build_meta' + +[project] +name = "mrmat-python-api-flask" +description = "Boilerplate code for an API using Flask" +urls = { "Sources" = "https://github.com/MrMatAP/mrmat-python-api-flask" } +keywords = ["experimental"] +readme = "README.md" +license = { text = "MIT" } +authors = [ + { "name" = "Mathieu Imfeld", "email" = "imfeldma+9jqerw@gmail.com" } +] +maintainers = [ + { "name" = "Mathieu Imfeld", "email" = "imfeldma+9jqerw@gmail.com" } +] +classifiers = [ + "Development Status :: 3 - Alpha", + "License :: OSI Approved :: MIT", + "Programming Language :: Python :: 3.11" +] +requires-python = ">=3.10" +dependencies = [ + "rich~=12.6.0", + "Flask~=2.2.2", + "Flask-SQLAlchemy~=3.0.2", + "Flask-Migrate~=4.0.0", + "flask-smorest~=0.40.0", + "Flask-Marshmallow~=0.14.0", + "marshmallow-sqlalchemy~=0.28.1", + "psycopg2-binary~=2.9.5", + "Flask-OIDC~=1.4.0" +] +dynamic = ["version"] + +[tool.setuptools.dynamic] +version = { attr = "ci.version "} + +[tool.setuptools.packages.find] +where = ["src/python"] +include = ["mrmat_python_api_flask*"] +namespaces = true + +[tool.setuptools.package-data] +"*" = ["*.mo", "migrations/*", "templates/*", "static/*"] + +[project.scripts] +mrmat-python-api-flask = "mrmat_python_api_flask.cui:main" +mrmat-python-api-flask-client = "mrmat_python_api_flask.client:main" + +# If you are debugging your tests using PyCharm then comment out the coverage options +# in addopts +[tool.pytest.ini_options] +minversion = "6.0" +addopts = "--cov=mrmat_python_api_flask --cov-report=term --cov-report=xml:build/coverage.xml --junit-xml=build/junit.xml" +testpaths = ["tests"] +junit_family = "xunit2" +log_cli = 1 +log_cli_level = "INFO" +log_cli_format = "%(asctime)s [%(levelname)8s] %(message)s (%(filename)s:%(lineno)s)" +log_cli_date_format="%Y-%m-%d %H:%M:%S" diff --git a/pytest.ini b/pytest.ini deleted file mode 100644 index f589022..0000000 --- a/pytest.ini +++ /dev/null @@ -1,12 +0,0 @@ -# -# If you are debugging your tests using PyCharm then comment out the coverage options -# in addopts - -[pytest] -testpaths = tests -addopts = --cov=mrmat_python_api_flask --cov-report=term --cov-report=xml:build/coverage.xml --junit-xml=build/junit.xml -junit_family = xunit2 -log_cli = 1 -log_cli_level = INFO -log_cli_format = %(asctime)s [%(levelname)8s] %(message)s (%(filename)s:%(lineno)s) -log_cli_date_format=%Y-%m-%d %H:%M:%S diff --git a/requirements.txt b/requirements.txt index fc8ec84..93e5063 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,24 +5,27 @@ # Build/Test requirements -build~=0.8.0 # MIT -wheel~=0.37.1 # MIT -pylint~=2.14.5 # GPL-2.0-or-later -pytest~=7.1.2 # MIT -pytest-cov~=3.0.0 # MIT -pyjwt~=2.4.0 # MIT -python-keycloak~=2.1.1 # MIT +setuptools>=42.0.0 +build>=0.9.0 # MIT +wheel>=0.36.0 # MIT +pylint~=2.15.5 # MIT +pytest~=7.2.0 # GPL-2.0-or-later +pytest-cov~=4.0.0 # MIT +pyjwt~=2.6.0 # MIT +python-keycloak~=2.6.0 # MIT # Runtime requirements -rich~=12.5.1 # MIT -Flask~=2.1.3 # BSD 3-Clause -Flask-SQLAlchemy~=2.5.1 # BSD 3-Clause -Flask-Migrate~=3.1.0 # MIT -flask-smorest~=0.38.1 # MIT +rich~=12.6.0 # MIT +Flask~=2.2.2 # BSD 3-Clause +Flask-SQLAlchemy~=3.0.2 # BSD 3-Clause +Flask-Migrate~=4.0.0 # MIT +flask-smorest~=0.40.0 # MIT Flask-Marshmallow~=0.14.0 # MIT -marshmallow-sqlalchemy~=0.27.0 # MIT -psycopg2-binary~=2.9.3 # LGPL with exceptions +marshmallow-sqlalchemy~=0.28.1 # MIT +psycopg2-binary~=2.9.5 # LGPL with exceptions Flask-OIDC~=1.4.0 # MIT -requests_oauthlib~=1.3.1 # ISC + +# Do we need these? +#requests_oauthlib~=1.3.1 # ISC itsdangerous<=2.0.1 # BSD 3-Clause Must affix so JSONWebSignatureSerializer is known diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 433c54a..0000000 --- a/setup.cfg +++ /dev/null @@ -1,46 +0,0 @@ -[metadata] -name = mrmat-python-api-flask -version = attr: ci.version -author = Mathieu Imfeld -author_email = imfeldma+9jqerw@gmail.com -maintainer = Mathieu Imfeld -maintainer_email = imfeldma+9jqerw@gmail.com -long_description = file: README.md -license = MIT -url = https://github.com/MrMatOrg/mrmat-python-api-flask -classifiers = - Development Status :: 3 - Alpha - License :: OSI Approved :: MIT - Programming Language :: Python :: 3.9 - -[options] -package_dir = - =src/python -packages = find: -include_package_data = True -install_requires = - rich~=11.2.0 - Flask~=2.0.3 - Flask-SQLAlchemy~=2.5.1 - Flask-Migrate~=3.1.0 - flask-smorest~=0.37.0 - Flask-Marshmallow~=0.14.0 - marshmallow-sqlalchemy~=0.27.0 - psycopg2-binary~=2.9.3 - Flask-OIDC~=1.4.0 - requests_oauthlib~=1.3.1 - itsdangerous<=2.0.1 - -[options.entry_points] -console_scripts = - mrmat-python-api-flask = mrmat_python_api_flask.cui:main - mrmat-python-api-flask-client = mrmat_python_api_flask.client:main - -[options.packages.find] -where=src/python -exclude = - ci - -[options.package_data] -mrmat_python_api_flask.migrations = - * diff --git a/ci/__init__.py b/src/python/ci/__init__.py similarity index 100% rename from ci/__init__.py rename to src/python/ci/__init__.py diff --git a/src/python/mrmat_python_api_flask/__init__.py b/src/python/mrmat_python_api_flask/__init__.py index 0ddd4f0..50e0baf 100644 --- a/src/python/mrmat_python_api_flask/__init__.py +++ b/src/python/mrmat_python_api_flask/__init__.py @@ -25,6 +25,7 @@ import sys import os +import json import logging.config import secrets import importlib.metadata @@ -37,57 +38,6 @@ from flask_oidc import OpenIDConnect from flask_smorest import Api - -# -# Establish consistent logging -# The logger we obtain here is an operational logger, not the one logging requests. The former uses the matching -# logger '__name__', the latter uses 'werkzeug' - - -class RequestFormatter(logging.Formatter): - """ - Formatter for requests - """ - def format(self, record): - if has_request_context(): - record.blueprint = request.blueprint - record.url = request.full_path - record.remote_addr = request.remote_addr - record.user_agent = request.user_agent - else: - record.url = None - record.remote_addr = None - return super().format(record) - - -logging.config.dictConfig({ - 'version': 1, - 'formatters': { - 'default': { - 'class': 'logging.Formatter', - 'format': '%(asctime)s %(name)-22s %(levelname)-8s %(message)s' - } - }, - 'handlers': { - 'console': { - 'class': 'logging.StreamHandler', - 'level': 'INFO', - 'formatter': 'default' - } - }, - 'loggers': { - __name__: { - 'level': 'INFO', - 'handlers': ['console'], - 'propagate': False - } - }, - 'root': { - 'level': 'INFO', - 'formatter': 'default', - 'handlers': ['console'] - } -}) log = logging.getLogger(__name__) # @@ -146,7 +96,10 @@ def create_app(config_override=None, instance_path=None): app_config_file = os.path.expanduser(os.environ.get('APP_CONFIG', '~/etc/mrmat-python-api-flask.json')) if os.path.exists(app_config_file): log.info('Applying configuration from %s', app_config_file) - app.config.from_json(app_config_file) + with open(app_config_file, 'r', encoding='UTF-8') as c: + config = json.load(c) + app.config.from_object(config) + #app.config.from_json(app_config_file) if config_override is not None: for override in config_override: log.info('Overriding configuration for %s from the command line', override) diff --git a/src/python/mrmat_python_api_flask/client.py b/src/python/mrmat_python_api_flask/client.py index 4e34d40..859966c 100644 --- a/src/python/mrmat_python_api_flask/client.py +++ b/src/python/mrmat_python_api_flask/client.py @@ -50,7 +50,7 @@ def __init__(self, exit_code: int = 1, msg: str = 'Unknown Exception'): def oidc_discovery(config: Dict) -> Dict: - resp = requests.get(config['discovery_url']) + resp = requests.get(config['discovery_url'], timeout=60) if resp.status_code != 200: raise ClientException(exit_code=1, msg=f'Unexpected response {resp.status_code} from discovery endpoint') try: @@ -64,7 +64,8 @@ def oidc_device_auth(config: Dict, discovery: Dict) -> Dict: resp = requests.post(url=discovery['device_authorization_endpoint'], data={'client_id': config['client_id'], 'client_secret': config['client_secret'], - 'scope': ['openid', 'profile']}) + 'scope': ['openid', 'profile']}, + timeout=60) if resp.status_code != 200: raise ClientException(exit_code=1, msg=f'Unexpected response {resp.status_code} from device endpoint') try: @@ -82,7 +83,8 @@ def oidc_check_auth(config: Dict, discovery: Dict, device_auth: Dict): data={'grant_type': 'urn:ietf:params:oauth:grant-type:device_code', 'device_code': device_auth['device_code'], 'client_id': config['client_id'], - 'client_secret': config['client_secret']}) # client_secret only for keycloak + 'client_secret': config['client_secret']}, + timeout=60) # client_secret only for keycloak if resp.status_code == 400: body = resp.json() if body['error'] == 'authorization_pending': @@ -213,7 +215,8 @@ def main(argv=None) -> int: # We're using requests directly here because requests_oauthlib doesn't support device code flow directly resp = requests.get(f'http://{args.host}:{args.port}/api/greeting/v3/', - headers={'Authorization': f'Bearer {auth["id_token"]}'}) + headers={'Authorization': f'Bearer {auth["id_token"]}'}, + timeout=60) log.info('Status Code: %s', resp.status_code) log.info(resp.content) diff --git a/src/python/mrmat_python_api_flask/migrations/env.py b/src/python/mrmat_python_api_flask/migrations/env.py index aecfc76..ee59fb1 100644 --- a/src/python/mrmat_python_api_flask/migrations/env.py +++ b/src/python/mrmat_python_api_flask/migrations/env.py @@ -93,7 +93,6 @@ def process_revision_directives(context, revision, directives): connection=connection, target_metadata=target_metadata, process_revision_directives=process_revision_directives, - render_as_batch=True, **current_app.extensions['migrate'].configure_args ) diff --git a/tests/conftest.py b/tests/conftest.py index 884b689..c4eba45 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -271,7 +271,7 @@ def app(self, 'OIDC_CLIENT_SECRETS': auth['client_secrets_file'] }) with self._app.app_context(): - upgrade(directory=os.path.join(os.path.dirname(__file__), '..', 'migrations')) + upgrade(directory=os.path.join(os.path.dirname(__file__), '..', 'var', 'migrations')) db.create_all() yield self._app diff --git a/var/docker/Dockerfile b/var/docker/Dockerfile index 34c7ac0..3cd3a78 100644 --- a/var/docker/Dockerfile +++ b/var/docker/Dockerfile @@ -1,6 +1,6 @@ -FROM python:3.10.1-slim +FROM python:3.10.5-slim -ADD migrations /migrations +USER 0:0 COPY dist/mrmat_python_api_flask-*.whl / RUN \ groupadd -g 1000 flask \ @@ -9,19 +9,17 @@ RUN \ && chown -R 1000:1000 /app /app/instance USER 1000:1000 - ENV FLASK_APP=mrmat_python_api_flask RUN \ python -mvenv /app/venv \ && . /app/venv/bin/activate \ && python -m pip install --no-cache-dir -U pip setuptools wheel \ && pip install --no-cache-dir gunicorn \ - && pip install --no-cache-dir /mrmat_python_api_flask-*.whl \ - && flask db upgrade + && pip install --no-cache-dir /mrmat_python_api_flask-*.whl USER 0:0 RUN \ - rm -rf /mrmat_python_api_flask-*.whl /migrations + rm -rf /mrmat_python_api_flask-*.whl EXPOSE 8080 USER 1000:1000