osw-repair
Standalone Python package for validating and iteratively repairing OpenSidewalks ZIP datasets.
The package contains archive handling, validator integration, constrained
repair planning, candidate validation, data models, and the osw-repair CLI.
It has no dependency on FastAPI, Uvicorn, or the web UI.
Local install
For development, install directly from this directory in editable mode:
python3.12 -m venv .venv
source .venv/bin/activate
python -m pip install -e '.[dev]'
Set the model credentials when an invalid dataset needs model-assisted repair:
OPEN_ROUTER_KEY=your-key
# Optional overrides (defaults shown)
# OSW_MODEL_PROVIDER=openrouter
# OSW_MODEL=anthropic/claude-opus-4.5
# OSW_MODEL_REASONING_EFFORT=low
# OPEN_ROUTER_MODEL_FALLBACKS=anthropic/claude-haiku-4.5
Only OPEN_ROUTER_KEY is required for the default OpenRouter configuration.
Fallback model IDs are comma-separated and tried in order by OpenRouter.
OSW_MODEL also controls the model displayed in the UI; CLI --model overrides it.
For direct OpenAI access, set OSW_MODEL_PROVIDER=openai,
OSW_MODEL=gpt-5.6, and OPENAI_API_KEY=your-key. The legacy
OPENAI_MODEL setting remains supported when OSW_MODEL is unset.
CLI
osw-repair dataset.zip \
--output fixed-osw.zip \
--max-iterations 10 \
--max-errors 50
Structured debug traces are written to fixed-osw.trace/ by default. Pass
--trace-dir PATH to choose another directory.
The command exits with 0 when the resulting dataset is valid, 2 when the
repair budget is exhausted, and 1 for input, configuration, or API errors.
Python API
from pathlib import Path
from osw_repair.engine import RepairEngine
from osw_repair.config import create_repairer
from osw_repair.validator import OSWValidator
engine = RepairEngine(
validator=OSWValidator(max_errors=50),
repairer=create_repairer(),
max_iterations=10,
trace_dir=Path("repair-traces"),
)
result = engine.run(Path("dataset.zip"), Path("fixed-osw.zip"))
print(result.iterations)
The model receives validation findings and a small dataset manifest, then reads
only affected features, schema constraints, and references through bounded tools.
Identities/references, feature structure, and existing required fields are enforced
as immutable in Python. Geometry is protected except for exact coordinate rounding
when validation explicitly reports a precision limit. Optional rejected properties
and precision-only geometry repairs are handled deterministically; other model
turns are limited to one focused issue. Near-miss endpoints and polygon vertices
may be snapped to nodes already referenced by the feature within a strict
0.000001° tolerance. Non-improving candidates are discarded.
For duplicate IDs, records with no meaningful tags (properties containing only
structural fields such as _id) are removed before tagged records. If this does
not select one record, exact duplicates may be collapsed and conflicting point
IDs are deduplicated only when every existing spatial reference uniquely supports
one canonical record. Ambiguous duplicates remain untouched.
An ID-less node is preserved when exactly one unresolved reference matches its
coordinates, allowing its missing ID to be restored from topology evidence. Without
that unique evidence, an untagged node is removed first, followed by features with
dangling references. Invalid conditionally required values are replaced only when
the compatible active-schema branches permit exactly one value; otherwise the
affected feature is removed. Mandatory properties are not deleted or guessed.
Tests
pytest
Tests use fake validators and repairers and do not consume model tokens.
Publishing to PyPI
Two GitHub Actions workflows publish only this directory. The wheel contains
only the osw_repair library and CLI. Both workflows run tests, check metadata
and distribution contents to exclude service and UI code, and smoke-test the
installed wheel before publishing.
| Branch | Workflow | Destination | Version |
|---|---|---|---|
dev |
.github/workflows/publish-testpypi.yml |
TestPyPI | Base package version plus .dev<run-number>, such as 0.1.0.dev42 |
main |
.github/workflows/publish-pypi.yml |
PyPI | Version committed in osw-repair/pyproject.toml |
Both workflows trigger on pushes to their branch, including PR merges, only
when files under osw-repair/ change. Changes limited to the service, frontend,
or workflow files do not publish a package. GitHub Releases and tags do not
trigger publishing. Use branch protection to require PR merges if direct pushes
should be prohibited.
TestPyPI version changes happen only in the runner and are not committed back.
Before merging a production release into main, bump the package version in
osw-repair/pyproject.toml to an unused PyPI version. Registry versions cannot
be overwritten. Existing distribution files are skipped on reruns; a new
production version is still required to publish changed code.
One-time setup:
-
Create GitHub Actions environments named
DevelopmentandProductionunder repository Settings → Environments. RestrictDevelopmentto thedevbranch andProductiontomain. -
Create a separate API token on each registry using its account settings. Use a project-scoped token for
osw-repairwhen the project already exists; for an initial upload, use an account-scoped token, then replace it with a project-scoped token after the project is created. -
Add an environment secret named
PYPI_API_TOKENto each GitHub environment, with the matching registry's token:GitHub environment Secret name Secret value DevelopmentPYPI_API_TOKENToken from TestPyPI ProductionPYPI_API_TOKENToken from PyPI
The publishing jobs use ${{ secrets.PYPI_API_TOKEN }} from their selected
environment. TestPyPI and PyPI tokens are separate credentials. Trusted Publisher
configuration is not required for these token-based workflows. The package name
must be available or owned by the token's account on each registry.
After a successful production release, users can install the core package with:
python -m pip install osw-repair
Metadata
Release files for osw-repair 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| osw_repair-0.1.0.tar.gz | 36.8 kB | Without provenance | Details for osw_repair-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| osw_repair-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for osw_repair-0.1.0-py3-none-any.whl |
Total release size: 66.1 kB
Release files / osw_repair-0.1.0.tar.gz
| Download URL | osw_repair-0.1.0.tar.gz |
|---|---|
| Size | 36.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f0bc9c30388bbfb70829e0e803837356c29069068cc68b32f0ccf2c957271fcc
|
|
BLAKE2b-256 checksum How to use checksums |
013646b8ec71c3aca880b4fbc982de4d294fc68c51b2e21956754196db839329
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Release files / osw_repair-0.1.0-py3-none-any.whl
| Download URL | osw_repair-0.1.0-py3-none-any.whl |
|---|---|
| Size | 29.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d319a5b20f2dcea0234b9f9e85ec09c69c7708d6195015efc11b7b7845e54977
|
|
BLAKE2b-256 checksum How to use checksums |
5746bb3db897b02f57a09f2201e13fa344ce18d52f27e16acef8fb27e9f4f141
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Security for osw-repair 0.1.0
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.