pyhusk
For FastAPI monorepos

Your Docker image doesn’t need your whole monorepo.

pyhusk traces what each service actually imports — including the Depends() chains its routes reach — and builds an image with only that.

View on GitHub Quickstart

pyhusk init  ·  pyhusk build  ·  pyhusk plan --json

How it works

Three steps, all automatic. No Dockerfiles to hand-maintain per service.

1

Discover

Imports the service's app, walks its routes and their Depends() trees to find every module a request can actually reach.

2

Prune

Follows the import graph from there, then resolves the transitive package closure from your lockfile — nothing unreferenced comes along.

3

Build & verify

Builds the image, boots it, and checks its OpenAPI schema (or a healthcheck) before calling the build done.

See it run

A two-service monorepo. One shared module, one service that doesn't use it.

Terminal recording of pyhusk list and pyhusk build against a two-service demo repo

What it checks for you

The parts that are easy to get wrong by hand.

Runtime dependencies, not just imports

A route can reach code only through Depends(). pyhusk walks that tree at introspection time, not just the static AST.

Rebuilds only what changed

Content-hash staleness, stamped as a registry label so it survives ephemeral CI runners — not a local file that resets every run.

Shared base images

Services with identical dependencies build one base image once, deterministically, regardless of which other services are in the same run.

Verified before it's tagged

Schema comparison when OpenAPI is on, a healthcheck poll when it isn't, boot-only as the last resort — and a failed check untags the image so it's retried, not silently kept.

CI-ready by default

pyhusk plan --json reports which services are stale, so a matrix job builds only those — no bespoke scripting.

Escape hatches when it guesses wrong

--include forces a path into the slice; --compare builds a whole-repo image alongside it so you can see whether pruning actually helped.

Quickstart

Python 3.12+, a uv-managed monorepo, and Docker.

# from your monorepo root
uv tool install pyhusk
pyhusk init          # writes pyhusk.yaml from detected services
pyhusk list
pyhusk build         # builds every stale service