Plain is headed towards 1.0! Subscribe for development updates →

Packages

Install Python modules as Plain packages.

Most Python modules that you use with Plain will need to be installed via settings.INSTALLED_PACKAGES. This is what enables template detection, per-package settings, database models, and other features.

A package can either be a local module inside of your app, or a third-party package from PyPI.

# app/settings.py
INSTALLED_PACKAGES = [
    "plain.models",
    "plain.tailwind",
    "plain.auth",
    "plain.passwords",
    "plain.sessions",
    "plain.htmx",
    "plain.admin",
    "plain.elements",
    # Local packages
    "app.users",
]

Creating app packages

It often makes sense to conceptually split your app across multiple local packages. For example, we find it typically works better to have separate users, teams, and projects packages, than a single core package that contains all the code for users, teams, and projects together (just as an example). If you find yourself creating a package with a generic name like core or base, you might want to consider splitting it up into smaller packages.

You can quickly create a new package by running plain create <package_name>. Make sure to add it to settings.INSTALLED_PACKAGES if it uses templates, models, or other Plain-specific features.

Package settings

An installed package can optionally define it's own settings. These could be default settings for how the package behaves, or required settings that must be configured by the developer.

# <pkg>/default_settings.py
# A default setting
EXAMPLE_SETTING: str = "example"

# A required setting (type annotation with no default value)
REQUIRED_SETTING: str

Settings can then be accessed at runtime through the settings object.

# <pkg>/models.py
from plain.runtime import settings


def example_function():
    print(settings.EXAMPLE_SETTING)

It is strongly recommended to "namespace" your settings to your package. So if your package is named "teams", you might want to prefix all your settings with TEAMS_.

# teams/default_settings.py
TEAMS_EXAMPLE_SETTING: str = "example"

Package ready() method

To run setup code when your package is loaded, you can define a package configuration and the ready() method.

# <pkg>/config.py
from plain.packages import PackageConfig, register_config


@register_config
class TeamsConfig(PackageConfig):
    def ready(self):
        print("Teams package is ready!")