Skip to main content

Reusable profiler and importer chassis for tabular migrations

Project description

migration-workbench

Reusable Django chassis for tabular workbook → app migrations: connectors pull from spreadsheets (Google Sheets) or Coda; profiling produces deterministic bundles; importers validate and apply with structured summaries; the workbook app turns profiles into schema-contract YAML for product repos to harden into real models.

PyPI: migration-workbenchpip install migration-workbench (import package migration_workbench uses underscores).

Who it is for

  • Product teams moving messy spreadsheet truth into a maintainable Django app.
  • Single-operator or small teams who want a repeatable pipeline (profile → contract → import) instead of one-off scripts.
  • Django-adjacent adopters comfortable wiring INSTALLED_APPS, env vars, and Fly-style SQLite hosting.

Three ways to use it

1. As a library (recommended for product repos)
Add the apps you need to INSTALLED_APPS and wire URLs/commands in your Django project. Set **DJANGO_SETTINGS_MODULE** to your project’s settings module (not migration_workbench.settings) in production. Depend on a released version, e.g. migration-workbench>=0.1.0,<1.

2. Scaffold a new product repo
From a sibling checkout of this repo:

make new-product PRODUCT=my-product   # writes ../my-product; git init + initial commit
make new-product PRODUCT=my-product PROVIDER=--coda

Then cd ../my-product && make install && make migrate && make check. Local make install matches the Dockerfile: the product package is editable (pip install -e .) and migration-workbench comes from PyPI via pyproject.toml. The scaffold also includes backend/, Makefile, scripts/entrypoint_product.sh, SQLite/Fly-aligned settings (SQLITE_PATH, /healthz, WAL pragmas), starter docs, and provider-specific config skeletons under config/ (Google Sheets by default; use PROVIDER=--coda for Coda). If git is on PATH, the scaffold initializes a repo and writes one initial commit using a scaffold-local author identity. Use --output-dir / --force on scripts/new_product.py for non-default paths.

3. Develop the chassis (this repo)
Clone, editable install, run the full gate:

python3 -m venv .venv
.venv/bin/pip install -e ".[dev]"
. ./.env.example   # or create .env
.venv/bin/python manage.py migrate
make chassis-gate

Quickstart (PyPI)

python3 -m venv .venv
.venv/bin/pip install "migration-workbench[dev]"   # omit [dev] if you skip pytest/black

Use wb on your PATH, or import apps (connectors, profiler, importer, workbook, deployment, …). For consumer repos installing the chassis next to your code: pip install -e ../migration-workbench — see profiler/README.md for profiling commands and importer/README.md for import authoring.

Core bundle commands (from a project with manage.py):

python manage.py pull_bundle --config docs/examples/live-config.example.json --output-dir /tmp/bundle
python manage.py snapshot_bundle --config docs/examples/offline-config.example.json --output-dir /tmp/bundle
python manage.py import_reference_example example_data --validate-only

Note: bundled **migration_workbench.settings** is for development; production hosts use their own settings module.

Architecture at a glance

Five Django apps:

App Role
connectors Provider adapters (Sheets, Coda).
profiler Read-only profiling → normalized bundle artifacts.
importer BaseImportCommand chassis, preflight/apply, summary JSON.
workbook scaffold_workbook_schema → schema-contract YAML.
deployment Manifest validation, wb CLI (manifest lint, deploy dry-run).
flowchart LR
  sourceConfig[SourceConfigJSON] --> pullBundle[PullBundleCommand]
  pullBundle --> providerRouter[ProviderRouter]
  providerRouter --> adapters[GoogleSheets_or_Coda]
  adapters --> rawRows[RawRows]
  rawRows --> normalizer[SpreadsheetNormalizer]
  normalizer --> bundle[NormalizedBundle]
  bundle --> importer[BaseImportCommandSubclass]
  importer --> summary[SummaryArtifactJSON]

More detail: docs/architecture.md.

The pipeline

  1. Intake — Source config (Drive folder, sheet IDs, Coda doc URLs).
  2. Profile — Profiler commands emit JSON/Markdown under product-owned data/profile_snapshots/ by default.
  3. Modelscaffold_workbook_schema produces schema-contract YAML for review.
  4. Harden — Importer tiers validate then apply; summary artifacts record outcomes.
  5. Deploywb manifest lint validates deploy/spaces.yml; wb deploy <space> --env <preview|production> --dry-run plans releases (provider mutation deferred — see docs/deployment.md).

Deployment

Fly.io + SQLite on a persistent volume + Litestream replication to Tigris or any S3-compatible bucket. Operator bootstrap, secrets, CI/CD, rollback, and roadmap for the wb control plane: docs/deployment.md.

CI/CD

Workflow File Trigger Role
CI .github/workflows/ci.yml push, PR make chassis-gate, wheel smoke
Deploy .github/workflows/deploy.yml after successful CI (workflow_run) manifest lint → flyctl deploy/healthz smoke (main → production, preview/* → preview)
Publish PyPI .github/workflows/publish-pypi.yml tag v* Trusted Publishing to PyPI

GitHub repository secret **FLY_API_TOKEN** is required for Deploy. Product repos can copy these CI patterns, but workflow files are maintained per repository.

Status and roadmap

Stable on 0.x today

  • Profiler (Google Sheets / Drive + Coda), importer chassis, workbook scaffolder.
  • wb manifest lint, wb deploy --dry-run, PyPI trusted publishing.
  • Self-hosted Fly path: Litestream + shared Tigris bucket, fly.toml / fly.preview.toml, entrypoint migrations.

In flight

  • Align default Git branch with Deploy workflow (main vs master).
  • Production Deploy workflow green end-to-end after secrets and Fly bootstrap.

Next

  • Real wb deploy (today: flyctl deploy + manifest lint is the operator path).
  • Backup/restore drill documented and exercised for the workbench space.
  • Google auth runbook evolution toward WIF (docs/google-auth.md).
  • Scaffold-delivered CI/CD templates for client product repos.

Later

  • Provider interface extraction after a second space is stable on Fly.
  • Postgres mode where concurrent writes demand it.

v1.0 criteria

The pipeline is exercised toward v1.0 via a product test repo (farm). v1.0 is reached when:

  1. End-to-end pipeline — All five stages (Connectors → Profiler → Importer → Workbook → Deployment) exercised on a real corpus via the product repo.
  2. Schema design loop completed — At least one source corpus has gone through Profile → Observe → Draft → Decide → Author config → Author importer → Gate → Drift check.
  3. Production deployment live — A scaffolded product is deployed to Fly.io with real imported data, health-check passing.
  4. PyPI release cut — All gaps identified during the test run are patched upstream, and a new PyPI release is published.

Semantic versioning applies; **0.x** may ship breaking changes — pin ranges in product repos.

Releases

  1. Bump **version** in [pyproject.toml](pyproject.toml).
  2. Tag **v + version** (must match version = "x.y.z").
  3. Trusted Publishing on PyPI for this repo (see publish workflow).

Manual upload: python -m build then twine upload dist/*, or make publish with maintainer credentials. Optional extras: [release] for build/twine only.

Documentation map

Doc Purpose
This README Orientation, pipeline, roadmap
docs/architecture.md Layered design
docs/deployment.md Fly, secrets, Litestream/Tigris, CI/CD, control-plane roadmap
docs/schema-design-loop.md Contract-first importer workflow
docs/google-auth.md Sheets/Drive profiling auth
docs/google-corpus.md Drive folder / multi-workbook Sheets corpus profiling
docs/coda.md Coda profiling
Per-package README.md under connectors/, profiler/, importer/, workbook/, deployment/ App-local surfaces

Changelog

0.1.3 (unreleased)

  • Backport AbstractUser admin scaffold support from codegen pipeline.
  • Extend contract schema to v1.2: enums, admin config, model_base, richer Meta.
  • Initial codegen pipeline: generate_models, generate_admin, generate_import commands producing production Django files from hardened schema-contract YAML.
  • Import generator base class with override hooks.
  • inject_project_local_config.sh helper for per-checkout config injection.

0.1.2

  • Default profile output directory: data/profile_snapshots/.
  • Drive folder tree rendered as Markdown artifact.
  • Cohort corpus resume support with workbook index and HTTP 429 retry.
  • Skeleton config files and raw_notes bucket included in new-product scaffold.
  • New product scaffold emits fixed Makefile referencing editable workbench path.
  • Bundle reader integration with YAML config files.

0.1.1

  • View manifest draft YAML artifact from profiler structural pass.
  • structure.json artifact from pull_bundle command — tab- and column-level metadata.
  • New product scaffold defaults to PyPI migration-workbench.
  • read_bundle_tab wrapper for normalizing rows from bundle tab CSV.
  • Git init and initial commit after new-product.
  • Consolidated docs folder with cross-cutting operator notes.
  • Per-app READMEs at connectors/, profiler/, importer/, workbook/, deployment/.

0.1.0

  • Initial scaffold: profile, import, bundle commands.
  • Project bootstrap scripting (new-product).
  • Google Sheets / Drive and Coda adapters.
  • Deployment documentation for Fly.io + Litestream.

Database modes

  • DB_ENGINE=sqlite (default)
  • DB_ENGINE=postgres with DB_NAME, DB_USER, DB_PASSWORD, DB_HOST, DB_PORT

License

See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

migration_workbench-0.2.0.tar.gz (158.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

migration_workbench-0.2.0-py3-none-any.whl (202.9 kB view details)

Uploaded Python 3

File details

Details for the file migration_workbench-0.2.0.tar.gz.

File metadata

  • Download URL: migration_workbench-0.2.0.tar.gz
  • Upload date:
  • Size: 158.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for migration_workbench-0.2.0.tar.gz
Algorithm Hash digest
SHA256 2ba1a36a9db56a1b7e4b08017fdf0b8642ba9101e82594645345d6dff9549fc4
MD5 66ebde5ae1ab692d28a324c3f6ba978d
BLAKE2b-256 4ebf4218eabffa66425aa6685690993a85a73c4111d246e65f0cef4d3b5b8b98

See more details on using hashes here.

Provenance

The following attestation bundles were made for migration_workbench-0.2.0.tar.gz:

Publisher: publish-pypi.yml on MrAllatta/migration-workbench

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file migration_workbench-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for migration_workbench-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b293fc3a027797b54510e0753a668e6194a3df10c05436214e5455682322cb65
MD5 ec9ba4ef688106791a11bd0412647480
BLAKE2b-256 4f9583569d18ef9ae65a6c29bf8e3307b497180d7a0fdcb8ddc4f7409f9d03f8

See more details on using hashes here.

Provenance

The following attestation bundles were made for migration_workbench-0.2.0-py3-none-any.whl:

Publisher: publish-pypi.yml on MrAllatta/migration-workbench

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page