supercontest

The South Bay Supercontest.

This is the app factory pattern.

All stdlib packages are imported at the toplevel. All first-party and third-party packages are intentionally lazy-loaded. Some hoisted to toplevel purely for types.

Functions

add_admin_panel

Adds the admin interface.

add_graphql

Adding graphql schemas and the interactive API.

add_preprocessor_for_g_attrs

Creates the root preprocessor for the flask application, hydrating all requests with some global attributes.

add_requester_printer

On each request, print the user's email for easy log inspection.

configure_app

Mutates the flask app with some configuration.

configure_cache

Initializes the cache.

configure_csrf

Initializes CSRF protection.

configure_database

Grabs the db URI, auth, and initializes the ORM.

configure_db_obj_serialization

Initializes the app with serialization capability, using marshmallow to pass database rows from serverside sqla to frontend js.

configure_logging

Configures the root logger to capture everything from all other loggers.

configure_migrations

Initializes alembic.

configure_smtp

Initializes mail.

configure_stripe

Adds the API key to the app configuration.

configure_user_manager

Attaches a context processor to the app which injects necessary user information into each request/session.

create_app

App factory.

get_config_dir

Fetches the path of the configuration directory.

get_package_info

Inspects the supercontest package version, to smartly set other extension configs.

inject_jinja_globals

Makes a few capabilities available to the templates.

minify_html

Minifies the templates for the app.

minify_js

Bundles and minifies the javascript.

print_loggers

Simply prints all the loggers in the application's python process.

register_blueprints

Adds the endpoints to the app.

set_env_modes

Establishes the modes of the app creation.

supercontest.add_admin_panel(app: Flask, db: SQLAlchemy) None

Adds the admin interface. Custom views for repetitive actions (like committing lines), as well as a model browser and much more.

Parameters:
  • app – The flask object.

  • db – The sqla object.

supercontest.add_graphql(app: Flask, csrf: Any) None

Adding graphql schemas and the interactive API. Intentionally allowing users in production to use graphiql to explore the db because it still requires auth.

Parameters:
  • app – The flask object.

  • csrf – The csrf object.

supercontest.add_preprocessor_for_g_attrs(app: Flask) None

Creates the root preprocessor for the flask application, hydrating all requests with some global attributes.

Parameters:

app – The flask app.

supercontest.add_requester_printer(app: Flask, logger: Logger) None

On each request, print the user’s email for easy log inspection.

Parameters:
  • app – The flask app.

  • logger – The logger to print with.

supercontest.configure_app(app: Flask, cfgdir: str) None

Mutates the flask app with some configuration.

Parameters:
  • app – The flask app to configure.

  • cfgdir – The path to configs.

supercontest.configure_cache(app: Flask, cfgdir: str) None

Initializes the cache.

Parameters:
  • app – The flask app.

  • cfgdir – Abs path to config dir.

supercontest.configure_csrf(app: Flask) Any

Initializes CSRF protection.

Parameters:

app – The flask app.

Returns:

The CSRF object.

supercontest.configure_database(app: Flask, cfgdir: str) SQLAlchemy

Grabs the db URI, auth, and initializes the ORM.

Parameters:
  • app – The flask app.

  • cfgdir – Abs path to config dir.

Returns:

SQLAlchemy object.

supercontest.configure_db_obj_serialization(app: Flask) None

Initializes the app with serialization capability, using marshmallow to pass database rows from serverside sqla to frontend js.

Parameters:

app – The flask app.

supercontest.configure_logging(app: Flask) Logger

Configures the root logger to capture everything from all other loggers. This includes the logger from this exact module, all other sbsc modules, flask’s logger (app.logger), and all other packages that have loggers without a custom handler and with propagate=True. basicConfig() just creates a streamHandler with the specified formats for the root logger.

Parameters:

app – The flask app.

Returns:

The logger for this module.

supercontest.configure_migrations(app: Flask, db: SQLAlchemy) None

Initializes alembic.

Parameters:
  • app – The flask app.

  • db – The sqla object.

supercontest.configure_smtp(app: Flask) None

Initializes mail.

Parameters:

app – The flask object.

supercontest.configure_stripe(app: Flask) None

Adds the API key to the app configuration.

Parameters:

app – The flask object.

supercontest.configure_user_manager(app: Flask, db: SQLAlchemy) None

Attaches a context processor to the app which injects necessary user information into each request/session.

Parameters:
  • app – The flask app.

  • db – The sqla object.

supercontest.create_app(test: bool = False) Flask

App factory. This toplevel package provides a single function which returns the configured flask app. All modules are lazy loaded, and protected by logic based on env vars for the mode that the app is running in.

Parameters:

test – Whether or not to run the app in test mode.

Returns:

Flask app.

supercontest.get_config_dir() str

Fetches the path of the configuration directory.

Returns:

Absolute path of config dir.

supercontest.get_package_info() tuple[str, str]

Inspects the supercontest package version, to smartly set other extension configs.

Returns:

SBSC package name and version.

supercontest.inject_jinja_globals(app: Flask) None

Makes a few capabilities available to the templates. This isn’t dynamic info (like a new user registering, and thus appearing in the id_name_map) because that could change on any request. These are constants that are initialized on the start of the application (ie changing them would require a redeploy of the app).

Parameters:

app – The flask app.

supercontest.minify_html(app: Flask) None

Minifies the templates for the app.

Parameters:

app – The flask app.

supercontest.minify_js(app: Flask) None

Bundles and minifies the javascript.

Parameters:

app – The flask app.

supercontest.print_loggers() None

Simply prints all the loggers in the application’s python process.

supercontest.register_blueprints(app: Flask) None

Adds the endpoints to the app.

Parameters:

app – The flask object.

supercontest.set_env_modes(app: Flask, test: bool) None

Establishes the modes of the app creation. These are used to condition other instantiations in the app factory, which generally flow in order of criticality. Here’s the order of app complexity, in terms of mode (and thus how quickly the app factory returns without extra configuration): Test -> CLI -> Dev -> Prod.

Note that modes are independent. You can have multiple (or none) be true.

We don’t pass booleans around for modes. They’re written to the app. This allows other extensions (as well as sbsc itself) to piggyback on them.

  • app.config["TESTING"] (test mode)

  • app.config["CLI"] (cli mode)

  • app.config["DEBUG"] (dev mode)

Test mode just instantiates app-related things, like the routes/blueprints. It is passed from the factory itself.

CLI mode is for dropping into the flask CLI. The factory is still called, but needs less configuration. This is primarily used for flask-migrate, for commands like flask db <> to run alembic migrations. It is set as an env var from the makefile.

Dev vs prod is the primary distinction. Flask prefers debug mode be set from the command line, but SBSC is frontend by gunicorn, so there’s no command line invocation (and no flask.run() python invocation for the debug arg). So we set in the docker compose file as an env var. As for gunicorn itself being dev vs prod: that’s set in the gunicorn config.

Parameters:
  • app – The flask app.

  • test – Passed through create_app().

Modules

comms

Functionality for communications, eg email notifications.

core

All of the critical, foundational functionality of the app.

dbsession

Wrappers around all interactions data.

forms

A collection of forms that allow user input on the client.

graphql

Most the app is REST, but we expose a graph for users to query directly.

models

Tables/schemas for the app.

util

All supercontest utilities.

views

The routes of the supercontest.