Skip to main content

Canonical Webteam Flask-Base

Flask extension that applies common configurations to all of webteam's flask apps.

Usage

from canonicalwebteam.flask_base.app import FlaskBase

app = FlaskBase(__name__, "app.name")

Or:

from canonicalwebteam.flask_base.app import FlaskBase

app = FlaskBase(
    __name__,
    "app.name",
    template_404="404.html",
    template_500="500.html",
    favicon_url="/static/favicon.ico",
)

Local development

For local development, it's best to test this module with one of our website projects like ubuntu.com. For more information, follow this guide (internal only).

Features

Logging

Logging is divided in 2 types depending on the environment:

  • Prod: uses a simple structured logging, that outputs JSON so that logs are searchable in tools like Grafana.
  • Dev: uses the Rich package to output logs to the terminal with colors to make them easier to look at.

The logging configuration is set in the root logger, so every logger that you generate like this

import logging
logger = logging.getLogger(__name__)

will use by default the handler set for the root logger and will be output properly. This includes logs in 3rd party packages too.

You can log custom JSON using the "extra" argument. Example:

logger.error("This is a test log with extra arguments", extra={
    "test": "I can add any JSON item",
    "test2": "In this extra dictionary",
    "number": 42,
})

The Gunicorn loggers are set up in a way that they don't use the root logger. If you want to get the same type of logs than the rest you need to execute your application passing the 'logger-class' attribute:

gunicorn webapp.app:app --logger-class canonicalwebteam.flask_base.log_utils.GunicornDevLogger ...

Configuring logging

The logging defaults set are good for probably most of the cases and teams, but in case of specific needs you can pass to FlaskBase a 'handler' object so that each project can configure logging to their liking. The 'handler' has to be of type logging.Handler. Example:

app = FlaskBase(..., handler=myHandler)

Tracing

If tracing is enabled in the project then you can get the trace ID of a request using

from canonicalwebteam.flask_base.opentelemetry.tracing import get_trace_id
trace_id = get_trace_id()

The trace ID will also be added by default to all the logs your application prints when it is available.

Tracing is enabled when setting up the tracing relation for an application that uses paas-charm.

Configuring tracing

There is a parameter that has been added to FlaskBase constructor in order to exclude certain routes from being traced.

app = FlaskBase(..., untraced_routes=["/demo"])

By default, just the "/_status" route is ignored.

Per route metrics

If a statsd-client is configured (which is enabled by default with 12f apps), FlaskBase will automatically add per route metrics. Including error counts, request counts, and response times.

ProxyFix

FlaskBase includes ProxyFix to avoid SSL stripping on redirects.

Redirects and deleted paths

FlaskBase uses yaml-responses to allow easy configuration of redirects and return of deleted responses, by creating redirects.yaml, permanent-redirects.yaml and deleted.yaml in the site root directory.

Error templates

FlaskBase can optionally use templates to generate the 404 and 500 error responses:

app = FlaskBase(
    __name__,
    "app.name",
    template_404="404.html",
    template_500="500.html",
)

This will lead to e.g. http://localhost/non-existent-path returning a 404 status with the contents of templates/404.html.

Redirect /favicon.ico

FlaskBase can optionally provide redirects for the commonly queried paths /favicon.ico, /robots.txt and /humans.txt to sensible locations:

from canonicalwebteam.flask_base.app import FlaskBase

app = FlaskBase(
    __name__,
    "app.name",
    template_404="404.html",
    template_500="500.html",
    favicon_url="/static/favicon.ico",
    robots_url="/static/robots.txt",
    humans_url="/static/humans.txt"
)

This will lead to e.g. http://localhost/favicon.ico returning a 302 redirect to http://localhost/static/favicon.ico.

Clear trailing slashes

Automatically clears all trailing slashes from all routes.

Jinja2 helpers

You get two jinja2 helpers to use in your templates from flask-base:

  • now is a function that outputs the current date in the passed format - {{ now('%Y') }} -> YYYY
  • versioned_static is a function that fingerprints the passed asset - {{ versioned_static('asset.js') }} -> static/asset?v=asset-hash

HTTP headers

You get the following headers automatically set:

  • X-Content-Type-Options: NOSNIFF
  • Permissions-Policy: interest-cohort=()
  • X-Frame-Options: SAMEORIGIN, which can be excluded with exclude_xframe_options_header decorator
  • Cache-Control if response.cache_control.* not set and according to static asset versioning (see versioned_static above)

security.txt, robots.txt and humans.txt

If you create a security.txt, robots.txt or humans.txt in the root of your project, these will be served at /.well-known/security.txt, /robots.txt and /humans.txt respectively.

/_status/check endpoint

Automatically adds the /_status/check endpoint which is used by content-caches for backend health checking or e.g. by k8s for checking the status of pods.

Custom gunicorn gevent worker

Included is a custom gunicorn gevent worker designed to handle SIGINT and SIGTERM gracefully, by closing all client connections and logging the stacktrace before exiting.

Usage

Run gunicorn in the usual way, but specify the worker class as LogWorker.

gunicorn webapp.app:app \
    -k canonicalwebteam.flask_base.worker.LogWorker

Planned features

  • Add support for open telemetry tracing. Using opentelemetry-instrumentation-flask and opentelemetry-exporter-otlp.

Tests

To run the tests execute SECRET_KEY=fake python3 -m unittest discover tests.

Metadata

Release files for canonicalwebteam.flask-base 3.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for canonicalwebteam.flask-base 3.1.2
File Size Uploaded
canonicalwebteam_flask_base-3.1.2.tar.gz 28.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for canonicalwebteam.flask-base 3.1.2
File Interpreter ABI Platform
canonicalwebteam_flask_base-3.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 60.6 kB

Release files / canonicalwebteam_flask_base-3.1.2.tar.gz

Download URL canonicalwebteam_flask_base-3.1.2.tar.gz
Size 28.5 kB
Tags Source
SHA-256 checksum
How to use checksums
2dd58c123e9e1483518200a5d704f485dc9cecf815c01b366226350118b80d39
BLAKE2b-256 checksum
How to use checksums
2be57432354f815afbd1feabe853f2e0b3237c9321628bcb604ecc738e78a553
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.7

Release files / canonicalwebteam_flask_base-3.1.2-py3-none-any.whl

Download URL canonicalwebteam_flask_base-3.1.2-py3-none-any.whl
Size 32.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7377bbba3cbbbdd20cad9d9bfdcc699f1ba6df93eedfc55587ccc0ae14158aba
BLAKE2b-256 checksum
How to use checksums
e407c46ba7bf19670d5923a6812aa39aacaceb2c3e4013956d7640465778665e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.7

Release history Release notifications | RSS feed

This release

3.1.2 This release

2 release files

3.1.1

2 release files

3.1.0

2 release files

3.0.0

2 release files

2.6.1

2 release files

2.6.0

2 release files

2.5.0

2 release files

2.4.0

2 release files

2.3.0

2 release files

2.2.1

2 release files

2.2.0

2 release files

2.1.0

2 release files

2.0.0

2 release files

1.1.0

2 release files

1.0.6

2 release files

1.0.5

2 release files

1.0.4

2 release files

1.0.3

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.0

2 release files

0.9.3

2 release files

0.9.2

2 release files

0.9.1

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.3

2 release files

0.7.2

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.4

2 release files

0.6.3

2 release files

0.6.2

2 release files

0.6.1

1 release file

0.6.0

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.3

2 release files

0.4.2

2 release files

0.4.1

2 release files

0.4

3 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page