A collection of Python packages for use in the Alliance Platform Django template.
Documentation: https://alliance-platform.readthedocs.io/
- Core (Documentation)
- Frontend (Documentation)
- Codegen (Documentation)
- Storage (Documentation)
- Audit (Documentation)
- UI (Documentation)
- PDF (Documentation)
- Server Choices (Documentation)
- Ordered Model (Documentation)
uv sync
# Setup git hooks and changesets, node_modules used for some tests
yarnNotes:
- This project uses uv for dependency management and uv workspaces with a single shared virtual environment for all packages during development. CI testing enforces true package isolation by testing each package separately.
- Package building uses pdm-backend as the build backend. This is a standalone PEP 517-compliant build backend that works with any build tool (including uv) and does not require PDM to be installed. The
[tool.pdm.*]sections in packagepyproject.tomlfiles are configuration for pdm-backend, not the PDM tool itself.
The project is structured as a monorepo, with each package in the packages directory. As a convention, each package
in here is named ap-<name>; this was chosen so it's not a valid python package name and is distinct from the underlying
package for ease of navigation / searching.
Each package has a namespaced package called alliance_platform, and
then within that the specific package name (e.g. frontend or codegen). This allows all Alliance Platform packages
to be imported from alliance_platform while being released and versioned independently.
# Default Python version (3.11 from .python-version)
just test-package ap-pdf
# Specific Python version
just test-package ap-pdf 3.12
# With Django constraint (matches CI behavior)
just test-package ap-pdf 3.12 django42 # Django 4.2.x
just test-package ap-pdf 3.12 django52 # Django 5.2.x# Default Python version
just test-all
# Specific Python version
just test-all 3.13
# With Django constraint (matches CI behavior)
just test-all 3.12 django42 # Test all packages with Python 3.12 + Django 4.2
just test-all 3.12 django52 # Test all packages with Python 3.12 + Django 5.2Tip: Use the constraint parameter to test locally with the same Django versions as CI!
cd packages/ap-pdf
uv run coverage run --source=alliance_platform ./manage.py test
uv run coverage reportThis is a monorepo with packages in packages/. Each package has its own pyproject.toml but shares a single workspace-level uv.lock file.
For runtime dependencies:
# packages/ap-pdf/pyproject.toml
[project]
dependencies = [
"playwright",
"Django>=4.2.11",
]For development/test dependencies:
# packages/ap-pdf/pyproject.toml
[dependency-groups]
dev = [
"factory-boy", # For test factories
"alliance-platform-frontend", # If testing integration with another package
]After modifying dependencies:
uv sync # Updates uv.lockThis is handled by ruff, and should automatically be run on commit. You can run it manually:
just lint # Run ruff linter
just format # Format code with ruff
just format-check # Check formatting without changes
# Without just:
uv run ruff check
uv run ruff check --fix
uv run ruff formatjust mypy-all # Type check all packages
just mypy-package ap-pdf # Type check specific package
# Without just:
cd packages/ap-pdf && uv run mypy .Build the documentation for all packages, serve it locally, and watch for changes:
just docs-watchCI runs parallel test jobs using GitHub Actions. Each job:
- Installs package-specific dependencies with
uv sync --package - Conditionally installs Playwright (only for packages that need it)
- Runs tests with coverage
- Uploads coverage to Codecov
When a change is made that requires a release the following workflow applies:
- Run
yarn changeset. Select the packages that have changed and the type of change (major, minor, patch). Add a description of the change. - This will create a new changeset file in the
.changesetdirectory. You can modify this file if needed to adjust the description. - Commit the changeset file and open a pull request.
- Once the PR is merged, a GitHub action will automatically create a PR to bump the version and publish the package to PyPI. If such a PR exists already, it will be updated with the new changeset.
- When that PR is merged, the package will be published to PyPI.
To add a new package, create a directory in packages/ named ap-<name>. It should contain a pyproject.toml file and
a package.json file; base these off the existing packages.
- Create a
pyproject.toml file. This is relatively straightforward, but you can base it off the existing packages. - Create a
package.jsonfile. This is only required so thatchangesetsknows a package exists to be versioned, and to store the version number. You just need to set thenamehere and choose the initialversion. - Create the structure of the package like other packages; a namespaced
alliance_platformpackage, and then the specific package name (e.g.frontendorcodegen). - Create a test app for the project, you can see
ap-frontend/test_alliance_platform_frontendfor an example. - Create a
manage.pyfile based on an existing package, and update"DJANGO_SETTINGS_MODULE". - Update
.github/workflows/ci.ymlto add the new package to the matrix of jobs. - In GitHub a new token for publishing will be needed. It should be added to the release environment secrets
as
ALLIANCE_PLATFORM_<upper case package name>_TOKEN. To create the token, go to PyPI and create a new token. The scope should be for the specific package only - if the package hasn't been published yet you can create one for all packages but you must re-create it after the initial publish and limit it to the specific package scope. Note that the PyPi Trusted Publishers would be good for this but I couldn't work out how to re-purpose it for our publishing workflow.- Update
.github/workflows/release.ymland add the token under theenvfor theCreate Release Pull Request or Publish to pypistep.
- Update
- Create a
docsdir, see existing package for an example.- Create an entry in
docs/conf.pyundermultiproject_projectsfor the new package. - In readthedocs.org, a new project needs to be created. To do this, import the https://github.com/AllianceSoftware/alliance-platform-py repo
again, but name it according to the package name (
alliance-platform-<name>). - Under the new project, go to Settings and Environment Variables. Add a new variable
PROJECTand name it the same as what the key inmultiple_projectsis. Check the 'Public' checkbox so it can be used in pull requests. - Go to Automation Rules and add a rule for detecting version tags. Set it to a custom match on tags with the pattern
alliance-platform-NAME@\d\.\d\.\d(where NAME is replaced with the package name) - Under settings check the
Build pull requests for this project:option. Set theURL versioning schemetoMultiple versions without translations - Then, under the main
alliance-platformsettings you can add it as a subproject.
- Create an entry in