Chapter 33: Architecture and Contributing¶
Part VII — Scaling, Migration & Reference
Learning Objectives¶
By the end of this chapter you will be able to:
- Recognize the design principles that hold the whole DisSModel ecosystem together
- Propose a new satellite package that fits the existing conventions
- Follow the contribution workflow, including the one CI-enforced detail specific to this codebase
# Standard imports
import numpy as np
import pandas as pd
This is the last chapter of the book, and it closes the way a good reference should: not with a new technique, but with the map of how everything else fits together. By now you've used a dozen separate repositories — dissmodel itself, dissmodel-ca, dissmodel-sysdyn, dissmodel-abm, disscube, dissmodel-platform, dissmodel-configs, and more — without any of them ever colliding or stepping on each other's code. That's not an accident; it's four consistent design decisions, repeated across every package.
Design Principles Observed Across the Ecosystem¶
- Minimal core, additive extensions.
dissmodel-ca,dissmodel-abm, anddissmodel-sysdynall depend ondissmodelthe way any ordinary Python package depends on another — none of them reaches back in and modifies the core itself. Chapter 24'sCellularAutomatondidn't require a single change todissmodel.core.Modelto exist. - Protective layers over the substrate. Chapter 25's
Society/Agentis the clearest example already in this book — model code reads and writes throughself.society, never throughself.gdfdirectly, so the underlying substrate can stay a plainGeoDataFramewithout every model needing to know that. - Configuration decoupled from code. Chapter 29's
dissmodel-configstreats every model's parameters as an external, pull-request-versioned registry — a TOML file, not something baked into the executor's own source. - One repository, one responsibility. Each simulation paradigm, each application domain, and each operational layer (the platform, the config registry, a QGIS plugin) gets its own repository, rather than one repository trying to be everything at once.
None of these four is enforced by any tool — nothing stops a new package from breaking one of them. They hold because every package that came before followed them, and a new one that doesn't stands out immediately.
How to Propose a New Satellite Package¶
Naming is close to consistent, not exactly one rule:
| Existing package | Pattern |
|---|---|
dissmodel-ca, dissmodel-sysdyn, dissmodel-abm |
dissmodel-<paradigm> |
disslucc-continuous, disslucc-discrete |
disslucc-<allocation-style> — a domain family of its own |
brmangue-dissmodel |
<domain>-dissmodel — reversed order |
disscube |
standalone, no prefix at all |
dissmodel-platform, dissmodel-configs |
dissmodel-<infra-role> |
A new paradigm extension, in the spirit of Chapters 23–25, fits dissmodel-<paradigm> naturally. A new application domain built on top of dissmodel can go either direction — dissmodel-<domain> or <domain>-dissmodel — the ecosystem simply isn't strict about that particular ordering.
A minimal structure, based on what every satellite package that has one actually ships — not every piece is present in every package:
your-package/
pyproject.toml # name, dependencies (dissmodel as a regular dep), version
src/your_package/
models/ # science layer only — Model/SpatialModel/RasterModel subclasses
executors/ # infrastructure layer, if you expose a ModelExecutor (Chapter 21, 22)
examples/
cli/ # or an executor's own CLI via run_cli — Chapter 22
streamlit/
notebooks/
tests/
docs/ + mkdocs.yml # present in some packages, absent in others — not universal
dissmodel-platform is the one deliberate exception: it has no pyproject.toml at all, because it's a deployed service — Docker Compose plus FastAPI (Chapter 29) — not something pip install-able in the first place.
Registering with the platform happens exactly one way: a TOML file added to dissmodel-configs/models/, following the <model>_<substrate>.toml convention Chapter 29 already introduced — executor_module, name, class, package (a git+https:// URL), and a [model.parameters] table — merged via a pull request. There is no second registration path.
Contribution Workflow¶
The workflow itself is the standard open-source shape, the same one many projects use — nothing DisSModel-specific until the very last point:
Reporting a bug. Open a GitHub issue with a descriptive title, clear reproduction steps, expected versus actual behavior, and environment details (OS, Python version, dissmodel version).
Suggesting an enhancement. An issue tagged "enhancement," explaining why the feature is useful and roughly how it should behave.
Pull requests. Fork the repository and branch from main; add tests for any new code; make sure the test suite passes; follow the project's existing coding style; then open the PR.
Development setup — the identical venv pattern Chapter 5 first taught:
git clone https://github.com/DisSModel/dissmodel.git
cd dissmodel
python -m venv venv && source venv/bin/activate
pip install -e ".[dev]"
pytest tests/
Coding standards: PEP 8, type hints where reasonably possible, NumPy-style docstrings.
One detail is worth calling out on its own, because it's easy to get wrong without knowing it exists: docstring examples written with >>> prompts run as real doctests in continuous integration, and every name they reference must be defined inside the example itself — no relying on an object built earlier in a notebook, the way this book's own chapters often chain code across cells. An example that needs outside context (an existing GeoDataFrame, a constructed Environment) should be a plain fenced ```python block instead — both render identically in the generated API documentation, but only the >>> form is actually checked in CI. Writing a >>> example that doesn't genuinely run won't just look sloppy; it will fail the build.
Known Risks and Areas of Attention¶
Closing this book on an unqualified success story would be dishonest — this same ecosystem's own materials are explicit about where it still has real gaps, and evaluating it seriously means knowing them:
- Bus factor. Maintenance is concentrated among a small number of maintainers, worth documenting explicitly for anyone funding or reviewing a project built on top of it.
- Test coverage. The core sits around 79% coverage; satellite packages don't yet report this metric in any standardized way.
- The platform is MVP-stage. Chapter 29 already flagged this directly — no security hardening yet, a real consideration before any production deployment.
disscubeis Alpha. Chapter 30's own declarative API is still evolving, a caveat that chapter also stated plainly rather than glossing over.
None of these block the core workflow this book has spent thirty chapters teaching — but treating them as current, honestly-stated facts rather than hidden weaknesses is itself part of what makes the rest of the ecosystem's documentation trustworthy.
Exercises¶
- Name a hypothetical package. You're building a satellite package implementing a new simulation paradigm not yet covered anywhere in this book — say, network diffusion models. Using How to Propose a New Satellite Package's naming table, what would you call it, and why does that pattern fit better than the alternatives?
- Spot a principle in code you've already run. Pick any model class from Chapters 23–25 and identify which of the four design principles in Design Principles it demonstrates most directly. Justify your choice in one sentence.
- Fix a broken doctest. Write a NumPy-style docstring example, using
>>>, for a function that depends on an already-constructedGeoDataFramefrom outside the example. Explain why this example would fail CI as written, and rewrite it in the form that actually would pass — or explain why it belongs in a plain fenced block instead. - Weigh a known risk. Pick one item from Known Risks and Areas of Attention and describe, in a sentence, a concrete decision it should change for someone planning to deploy a DisSModel-based system in production within the next year.
# Your code here
Summary¶
Key concepts introduced¶
- Four design principles holding the ecosystem together by convention, not enforcement: a minimal core with additive extensions, protective layers over the substrate, configuration decoupled from code, and one repository per responsibility
- A near-consistent naming pattern for new satellite packages, and the minimal file structure most of them share
- Registering a new model on the platform through exactly one path: a pull request to
dissmodel-configs - The standard open-source contribution workflow, plus one CI-enforced detail specific to this codebase —
>>>docstring examples run as real, self-contained doctests - Four honestly-stated known risks — bus factor, uneven test-coverage reporting, an MVP-stage platform, an Alpha-stage
disscube— treated as current state to plan around, not flaws to hide
That closes this book. Parts I and II gave you a geographic data science toolkit independent of any single framework; Part III built the concepts a spatial simulation needs by hand, one honest performance number at a time; Part IV handed those same concepts to DisSModel and showed what the framework buys you back; and Parts VI and VII took you past a single model run — into reproducibility, infrastructure, ensembles, migration, and now the architecture holding it all together. Where you take it from here is the same open, additive process this chapter just described.
Further Reading¶
- DisSModel's
CONTRIBUTING.md, the canonical reference this chapter's workflow section is based on: https://github.com/DisSModel/dissmodel/blob/main/CONTRIBUTING.md - PEP 8 — Style Guide for Python Code: https://peps.python.org/pep-0008/
- NumPy docstring standard: https://numpydoc.readthedocs.io/en/latest/format.html
- pytest documentation, Doctest integration: https://docs.pytest.org/en/stable/how-to/doctest.html