Skip to main content

Usage

  1. Install uv

  2. Install fh-fablib. The recommended way is to use uv tool install -e ~/projects/fh-fablib if you have a local git checkout you want to install from. Otherwise you can use uv tool install fh-fablib to install the packaged version.

  3. Add a fabfile.py to your project. A minimal example follows:

    import fh_fablib as fl
    
    fl.require("1.0.20260311")
    fl.config.update(host="www-data@feinheit06.nine.ch")
    
    environments = [
        fl.environment(
            "production",
            {
                "domain": "example.com",
                "branch": "main",
                "remote": "production",
            },
            aliases=["p"],
        ),
    ]
    
    ns = fl.Collection(*fl.GENERAL, *fl.NINE, *environments)
  4. Run fl hook to provide a default prek configuration (or fl hook --force to override the dotfiles).

  5. Run fl --list to get a list of commands.

Configuration values

  • app = "app": Name of primary Django app containing settings, assets etc.

  • base: pathlib.Path object pointing to the base dir of the project.

  • branch: Branch containing code to be deployed.

  • domain: Primary domain of website. The database name and cache key prefix are derived from this value.

  • environments: A dictionary of environments, see below.

  • environment: The name of the active environment or "default".

  • force: Always force-push when deploying.

  • host: SSH connection string (username@server)

  • remote: git remote name for the server. Only used for the fetch task.

  • _uv_project: Whether to use uv for project management. Defaults to True if uv.lock exists.

Adding or overriding bundled tasks

For the sake of an example, suppose that additional processes should be restarted after deployment. A custom deploy task follows:

# ... continuing the fabfile above

@fl.task
def deploy(ctx):
    """Deploy once 🔥"""
    fl.deploy(ctx)  # Reuse
    with fl.Connection(fl.config.host) as conn:
        fl.run(conn, "systemctl --user restart other.service")

ns.add_task(deploy)

Multiple environments

If you need multiple environments, add environment tasks as follows:

import fh_fablib as fl

fl.require("1.0.20260311")
fl.config.update(host="www-data@feinheit06.nine.ch")

environments = [
    fl.environment(
        "production",
        {
            "domain": "example.com",
            "branch": "main",
            "remote": "production",
        },
        aliases=["p"],
    ),
    fl.environment(
        "next",
        {
            "domain": "next.example.com",
            "branch": "next",
            "remote": "next",
        },
        aliases=["n"],
    ),
]

ns = fl.Collection(*fl.GENERAL, *fl.NINE, *environments)

Now, fl production pull-db, fl next deploy and friends should work as expected.

Available tasks

fh_fablib.GENERAL

  • check: Check the coding style

  • cm: Compile the translation catalogs

  • debug: Run development server with debugpy enabled

  • deploy: Deploy once 🔥

  • dev: Run the development server for the frontend and backend

  • fetch: Ensure a remote exists for the server and fetch

  • freeze: Freeze the virtualenv’s state

  • github: Create a repository on GitHub and push the code

  • hook: Install the prek hook

  • local: Local environment setup

  • mm: Update the translation catalogs

  • pull-db: Pull a local copy of the remote DB and reset all passwords

  • pull-media: Rsync a folder from the remote to the local environment

  • reset-pw: Set all user passwords to "password"

  • reset-sq: Reset all PostgreSQL sequences

  • update: Update virtualenv and node_modules to match the lockfiles

  • upgrade: Re-create the virtualenv with newest versions of all libraries

fh_fablib.NINE

  • nine: Run all nine🌟 setup tasks in order

  • nine-alias-add: Add aliasses to a nine-manage-vhost virtual host

  • nine-alias-remove: Remove aliasses from a nine-manage-vhost virtual host

  • nine-checkout: Checkout the repository on the server

  • nine-db-dotenv: Create a database and initialize the .env. Currently assumes that the shell user has superuser rights (either through PGUSER and PGPASSWORD environment variables or through peer authentication)

  • nine-disable: Disable a virtual host, dump and remove the DB and stop the gunicorn@ unit

  • nine-reinit-from: Reinitialize an environment from a different environment

  • nine-restart: Restart the application server

  • nine-ssl: Activate SSL

  • nine-unit: Start and enable a gunicorn@ unit

  • nine-venv: Create a venv and install packages from requirements.txt

  • nine-vhost: Create a virtual host using nine-manage-vhosts

Building blocks

The following functions may be used to build your own tasks. They cannot be executed directly from the command line.

Running commands

  • run(c, ...): Wrapper around Context.run or Connection.run which always sets a few useful arguments (echo=True, pty= True and replace_env=False at the time of writing)

Checks

  • _check_branch(ctx): Terminates if checked out branch does not match configuration.

  • _check_no_uncommitted_changes(ctx): Terminates if there are uncommitted changes on the server.

Helpers

  • _local_env(path=".env"): speckenv.env for a local env file

  • _srv_env(conn, path): speckenv.env for a remote env file

  • _python3(): Return the path of a Python 3 executable. Prefers newer Python versions.

  • _local_dotenv_if_not_exists(): Ensure a local .env with a few default values exists. Does nothing if .env exists already.

  • _local_dbname(): Ensure a local .env exists and return the database name.

  • _dbname_from_dsn(dsn): Extract the database name from a DSN.

  • _dbname_from_domain(domain): Mangle the domain to produce a string suitable as a database name, database user and cache key prefix.

  • _concurrently(ctx, jobs): Run a list of shell commands concurrently and wait for all of them to terminate (or Ctrl-C).

  • _random_string(length, chars=None): Return a random string of length, suitable for generating secret keys etc.

  • require(version): Terminate if fh_fablib is older.

  • terminate(msg): Terminate processing with an error message.

Deployment

  • _deploy_django: Update the Git checkout, update the virtualenv.

  • _deploy_staticfiles: Collect staticfiles.

  • _rsync_static: rsync the local static/ folder to the remote, optionally deleting everything which doesn’t exist locally.

  • _nine_restart: Restart the systemd control unit.

Metadata

Release files for fh-fablib 1.0.20260311

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

Source distribution (sdist)

Source distribution for fh-fablib 1.0.20260311
File Size Uploaded Provenance Actions
fh_fablib-1.0.20260311.tar.gz 27.3 kB Without provenance Details for fh_fablib-1.0.20260311.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for fh-fablib 1.0.20260311
File Interpreter ABI Platform Actions
fh_fablib-1.0.20260311-py3-none-any.whl Python 3 none any Details for fh_fablib-1.0.20260311-py3-none-any.whl

Total release size: 50.8 kB

Release files / fh_fablib-1.0.20260311.tar.gz

Download URL fh_fablib-1.0.20260311.tar.gz
Size 27.3 kB
Tags Source
SHA-256 checksum
How to use checksums
665d9b26f48196b0723adafe09e391a0a18954223a84a6ed5d96762d1f826e75
BLAKE2b-256 checksum
How to use checksums
133d8d648ac028a64adff15b46b919d8eb5596854250d54a3d6896ad4929bfac
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.0

Release files / fh_fablib-1.0.20260311-py3-none-any.whl

Download URL fh_fablib-1.0.20260311-py3-none-any.whl
Size 23.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a7367ba77005c84574af687637947aef036496ffc8d4c1e059b06ffad2ba33b6
BLAKE2b-256 checksum
How to use checksums
5aef66f059cf4335e881aae9aaf0b4226263fc2923764276912eec65ab5a38b1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.0

Security for fh-fablib 1.0.20260311

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.0.20260311 This release

2 release files No provenance

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