
Product
Socket Now Supports pylock.toml Files
Socket now supports pylock.toml, enabling secure, reproducible Python builds with advanced scanning and full alignment with PEP 751's new standard.
flask-container-scaffold
Advanced tools
A common base layer for Flask applications that are deployed in containers.
This project is still in a very early stage, being pulled out from a flask- based ReST service that was developed to be deployed in a container. The main issue it was created to solve was adding easy and consistent support for flexible configuration. For instance, in a development environment, there may be a configuration file that is used, but in a container, you may need to specify an environment variable that points to a yaml/json file, or some filesystem mount that is very different from development. Externalizing this configuration allows for more flexibility in multiple environments.
flask-container-scaffold can be installed via pip with:
pip install flask-container-scaffold
The library is meant to be used to do the basic configuration of a flask application, and allows for the user to then do any further setup required once the configuration is in place. It is called from within your app factory function like this:
app = AppScaffold(name=__name__, config=config).app
app.register_blueprint(foo.bp) # or whatever else you still need to do
The library supports two levels of configuration.
The first is the standard flask configuration that can be used by default, but with a bit of extra structure. You can specify this configuration using any or all of the following options:
Note that Flask requires all config settings to be in CAPS, otherwise they will not be included in the app.config dictionary on initialization.
AppScaffold will look for each of the items above, and they will be set in the same order, if found. So, for example, if you set:
config= {'FOO': 'bar'}
when you call AppScaffold, but then have:
FOO='something else'
in your file specified by the FLASK_SETTINGS environment variable, the latter will overwrite the former.
Custom settings are meant to be more flexible than the Flask settings, and can be in whatever structure makes sense for your application. These settings are found and loaded by AppScaffold when you reference a Flask setting of CUSTOM_SETTINGS in any of the following ways:
Currently, settings can be configured via a standard cfg file (using ini-file format) or a yaml file (which can end with '.yml' or '.yaml'). These files, in turn, can reference additional files if needed. Sections and structures are supported, so long as they can be put into a python dictionary, and will be added as-is, without additional formatting of case (which the python ConfigParser library does by default). Also, keys can be in whatever case suits your needs, which is a difference from the core Flask settings.
After the application is initialized, the custom formatter can be configured at any point in the code before logging is called. As an example:
from logging.config import dictConfig
from flask_container_scaffold.logging import FlaskRequestFormatter
dictConfig({
'version': 1,
'formatters': {
'default': {
'()': FlaskRequestFormatter,
'format': '[%(asctime)s] %(remote_addr)s '
'%(levelname)s in %(module)s: %(message)s',
},
},
'handlers': {
'wsgi': {
'class': 'logging.StreamHandler',
'stream': 'ext://flask.logging.wsgi_errors_stream',
'formatter': 'default'
},
'file': {
'class': 'logging.handlers.RotatingFileHandler',
'filename': '/var/log/myapp.log',
'backupCount': 3,
'maxBytes': 15728640, # 1024 * 1024 * 15
'formatter': 'default',
},
},
'loggers': {
'main': {
'level': 'INFO',
},
},
'root': {
'level': 'WARNING',
'handlers': ['wsgi', 'file'],
},
})
This class has all of the same support as the above AppScaffold and takes the same parameters. Each CeleryScaffold instance has a flask_app and celery_app attribute that can be used in your project. More information about celery can be found here. Information on integrating celery with flask can be found in flask's documentation.
pip install flask-container-scaffold['celery']
or
pipenv install --categories celery
celery_scaffold = CeleryScaffold(name=__name__, config=config)
flask_app = celery_scaffold.flask_app
celery_app = celery_scaffold.celery_app
All configuration is done via a 'CELERY' key in a configuration dictionary. The 'CELERY' element itself is a dictionary of configuration items. More details on the available configuration items for celery can be found here. Below is a basic example in yaml format that uses a local rabbitmq broker, json serialization, and no result backend.
---
CELERY:
broker: "pyamqp://guest@127.0.0.1//"
result_persistent: False
task_serializer: "json"
accept_content:
- "json" # Ignore other content
result_serializer: "json"
result_expires: "300"
broker_connection_retry_on_startup: 'False'
This method is used to validate incoming data against a pydantic model. A custom return type can be specifed in the case of validation failure, but it must extend flask_container_scaffold.BaseApiView, or minimally implement a field 'errors' of type dict, so that the parse_input method can properly populate it on a failure.
As an example of how to use this with a custom return type, let us assume you have created the following classes:
class ApiViewWithIntCode(BaseApiView):
code: int = 1
class MyCustomInput(ApiViewWithIntCode):
code: int = 0
name = str
Your desire here is to use 'code' to make decisions on what to do with the object returned by parse_input. This could be implemented in, for example, your resource like this:
model = parse_input(app.logger, MyCustomInput, ApiViewWithIntCode)
if model.code != 1:
# do something with MyCustomInput because we know it is valid
else:
# do something else because there was an error
You may set up your environment with virtualenv or another preferred tool for managing virtual environments, but here are some directions for doing so using pipenv. First, install pipenv:
pip install --user pipenv
Next, using it to set up your development environment:
pipenv update -d
If you prefer to use pip directly in your venv, specify the following requirements files:
There is also a dist-requirements.txt, if you will be building the project for distribution.
Any remaining directions will assume you are in your venv, which for pipenv, can be activated like this:
pipenv shell
Alternatively, any commands can be run in your pipenv venv by prepending with:
pipenv run
This project attempts to follow most of the suggestions in the python packaging docs while also supporting an easy to set up development environment.
If you wish to build the project for distribution:
python -m build
FAQs
Configuration layer to aid in deployment of Flask apps
We found that flask-container-scaffold demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Product
Socket now supports pylock.toml, enabling secure, reproducible Python builds with advanced scanning and full alignment with PEP 751's new standard.
Security News
Research
Socket uncovered two npm packages that register hidden HTTP endpoints to delete all files on command.
Research
Security News
Malicious Ruby gems typosquat Fastlane plugins to steal Telegram bot tokens, messages, and files, exploiting demand after Vietnam’s Telegram ban.