OpenSCAD generation toolkit + curated printable parts.
Apothecary composes OpenSCAD code from Python using Pydantic models. It provides a CLI, REST API, and web viewer for building and exploring 3D printable parts.
Interactive 3D parts browser with STL preview
- Pydantic-based primitives – Type-safe
Cube,Sphere,Cylinder, boolean ops, and transforms - Scene composition – Build complex models by combining simple objects
- CLI & API – Render scenes from JSON, serve via FastAPI, explore interactively
- Parts library – Curated printable parts with metadata, parameters, and STL generation
- Web viewer – Three.js-powered 3D browser with real STL rendering
- Elephant walk – Preview all parts arranged in a single view
- STL generation – Automatic OpenSCAD → STL conversion via API
- JSCAD export – Generate JavaScript modules for OpenJSCAD
# Install
git clone https://github.com/yourorg/apothecary.git
cd apothecary
uv sync
# Generate example
uv run apothecary testrun -o example.scad
# Explore parts
uv run apothecary parts list
# Start web viewer
uv run apothecary serve
# Open http://127.0.0.1:8000/viewer| Guide | Description |
|---|---|
| QUICKSTART.md | Get running in 5 minutes |
| docs/ | Full documentation index |
| docs/scene-json.md | JSON format for scenes |
| docs/parts-authoring.md | Add your own parts |
| CONTRIBUTING.md | Development setup & guidelines |
| CHANGELOG.md | Version history |
apothecary --help # Show all commands
# Core
apothecary testrun -o out.scad # Generate example scene
apothecary render --scene-file scene.json -o out.scad
apothecary render-jscad --scene-file scene.json -o out.js
# Parts
apothecary parts list # List available parts
apothecary parts info NAME # Show part details
apothecary parts render NAME # Generate include stub
apothecary parts generate-stl --all # Generate all STLs
apothecary parts elephant-walk # Generate all-parts preview
# Server
apothecary serve # Start FastAPI server
apothecary serve --port 8765 # Custom port
apothecary dev # Dev mode: generate STLs + start server
# Testing
apothecary test all # Run full suite (unit + E2E)
apothecary test all --coverage # With coverage report
apothecary test run # Unit tests only
apothecary test run-e2e # E2E tests only
# Development
apothecary inventory structure # Show repo layout
apothecary check # Verify installationStart the server and visit http://127.0.0.1:8000:
| Endpoint | Description |
|---|---|
/viewer |
Interactive 3D parts browser (Three.js) |
/docs |
OpenAPI documentation (Swagger) |
/parts |
List all parts (JSON) |
/parts/{name}/scad |
Download OpenSCAD source |
/parts/{name}/stl |
Download STL file |
/parts/{name}/stl/generate |
Generate STL from SCAD |
/openscad/status |
Check OpenSCAD availability |
/health |
Health check |
from apothecary import Scene, Cube, Sphere, Translate, Union, Vector3D
# Build a scene
base = Cube(size=Vector3D(x=20, y=20, z=5))
dome = Translate(v=Vector3D(x=10, y=10, z=5), children=[Sphere(r=8)])
scene = Scene(name="demo", objects=[Union(children=[base, dome])])
# Generate OpenSCAD
print(scene.render())
# Or JSCAD
print(scene.render_jscad())apothecary/
├── apothecary/ # Python package
│ ├── primitives.py # Cube, Sphere, Cylinder
│ ├── booleans.py # Union, Difference, Intersection
│ ├── transforms.py # Translate, Rotate, Scale
│ ├── scene.py # Scene composition
│ ├── api.py # FastAPI endpoints
│ ├── cli.py # Click CLI
│ ├── viewer.py # Three.js viewer
│ └── projects/parts/ # Part wrappers & STL renderer
├── parts/ # Part folders with .scad/.stl
│ ├── parametric_star/
│ ├── couch_block/
│ └── ...
├── templates/ # Jinja2 templates
├── tests/ # Test suite (unit + E2E)
└── docs/ # Documentation
# Unit tests only
uv run pytest -q
# Full test suite (unit + E2E with auto-server)
uv run apothecary test all
# With coverage
uv run apothecary test all --coverage
# E2E only (requires running server)
uv run apothecary serve --port 8765 # Terminal 1
uv run apothecary test run-e2e # Terminal 2STL files are not committed to git – they're generated locally from SCAD sources:
- On server startup: Missing STLs are auto-generated if OpenSCAD is installed
- Manual generation:
uv run apothecary parts generate-stl --all - Single part:
uv run apothecary parts generate-stl calibration_cube - Force rebuild: Add
--forceto regenerate existing STLs
To skip auto-generation at startup: APOTHECARY_SKIP_STL_GENERATION=1 apothecary serve
We welcome contributions! Please read CONTRIBUTING.md for:
- Development setup
- Code style guidelines
- Testing requirements
- Pull request process
MIT License. See LICENSE for details.