Publishing Your Work
How DispatchAtlas publishes evidence from its registries to the website — the flow from campaign results to public, disclosure-filtered portal surfaces.
DispatchAtlas auto-publishes from its registries straight to the website's
dedicated, viewable sections: a registered solver surfaces in the
Solver Recommender, an exported benchmark subset
becomes a downloadable bundle, and an exported campaign
result is rendered by the Results explorer. Every step uses
the installed public API -- no repository-only tooling -- so your own solvers,
benchmarks, and results reach the same surfaces the shipped ones do. The runnable
examples/publish_to_portal.py
walks the whole path end to end in under a second.
Publish a solver
A solver carries registry metadata (a profile). Register it into a
SolverRegistry, and a publicly-catalogued profile enters the public catalog the
portal renders:
from dispatchatlas.solve import SolverRegistry
catalog = SolverRegistry()
catalog.register_instance(your_solver)
published = {metadata.solver_id for metadata in catalog.public_catalog()}The registry-derived solver bundle the website serves carries every catalogued solver, so a registered public solver reaches the Solver Recommender with no extra step.
Publish a benchmark subset
Project any catalog into a portable, self-describing bundle and a flat CSV table -- the exact artifacts the portal's download center serves a visitor:
from dispatchatlas.bench import (
build_continuum_catalog,
catalog_metadata_for_sets,
catalog_subset_to_bundle,
catalog_subset_to_csv,
)
records = catalog_metadata_for_sets(build_continuum_catalog(root_seed=23))
bundle_bytes = catalog_subset_to_bundle(records) # a downloadable archive
csv_text = catalog_subset_to_csv(records) # a flat table of the same rowsBoth are the downloadable artifacts the Downloads center offers, and the full continuum catalog is already browsable in the Benchmark Catalog.
build_continuum_catalog materializes a fast three-resource preview -- ideal for
portal filtering and a quick look. For research-scale reference benchmarks, swap in
build_continuum_full_catalog, which builds each family at its declared scale -- a
larger resource pool and task count, where the co-allocation, contention, and
placement structure genuinely manifests -- and flows through the very same
catalog_metadata_for_sets and catalog_subset_to_bundle export surface:
from dispatchatlas.bench import build_continuum_full_catalog
research_records = catalog_metadata_for_sets(
build_continuum_full_catalog(root_seed=23, problem_count_per_family=4)
)
research_bundle = catalog_subset_to_bundle(research_records) # research-scalePublish from an installable package
The sections above register a solver or a generator from inside your own script.
For a reusable extension -- one another project installs and picks up without any
glue code -- DispatchAtlas reads packaging entry points, so an installed
distribution contributes solvers and benchmark generators without touching the
in-tree registries. Advertise a zero-argument provider under the matching
entry-point group in your package's pyproject.toml:
[project.entry-points."dispatchatlas.solvers"]
my-solvers = "my_package.providers:scheduling_solvers"
[project.entry-points."dispatchatlas.benchmark_generators"]
my-generators = "my_package.providers:scheduling_generators"Each target is a callable that takes no arguments and returns an iterable -- of
ProfiledSolver for the solver group, of BenchmarkGenerator for the generator
group -- the same shape the shipped providers return. Discovery is never
automatic, so the bundled catalogs stay deterministic; a caller opts in
explicitly:
from dispatchatlas.bench import GeneratorRegistry, discover_plugin_generators
from dispatchatlas.solve import default_solver_registry, discover_plugin_solvers
solvers = default_solver_registry()
discover_plugin_solvers(solvers) # ids of the third-party solvers registered
generators = GeneratorRegistry()
discover_plugin_generators(generators) # ids of the third-party generators registeredA discovered solver flows through the same register_instance path as the one
above, so a publicly-catalogued plugin solver reaches the
Solver Recommender with no extra step. Discovery is
fail-closed on evidence: a plugin solver that declares no citation reference, or a
generator that claims citation-backed status while citing no source, is rejected
before it enters a registry -- a third-party extension carries the same
citation-backed invariant the shipped catalog does.
Publish results
Run a campaign, then export it through a disclosure policy to the portal-results bundle the site's results explorer renders:
from dispatchatlas.analytica import (
AnalysisConfig,
EvidenceTier,
default_disclosure_policy,
load_result_dataset,
write_portal_dataset,
)
dataset = load_result_dataset(workspace, "your-campaign-id")
write_portal_dataset(
dataset,
default_disclosure_policy(EvidenceTier.CORE),
target_dir,
AnalysisConfig(objective_name="makespan"),
)write_portal_dataset writes a content-hashed portal-results.json filtered to
the declared disclosure tier -- the exact bundle the
Results explorer renders, so the export is your results
published to the portal. The disclosure filter is fail-closed: a result the tier
does not permit is never published, so a study cannot over-share by accident.
See it end to end
uv run python examples/publish_to_portal.pyThe example registers a solver, confirms it rides the portal solver bundle, exports a benchmark subset to a bundle and a CSV, and runs a campaign whose results export in the portal results-explorer format -- the whole publish path, read straight from the installed public API and the committed portal bundles the site ships.