Deterministic 3D cartonization and rectangular bin packing. Pure Python, no runtime dependencies, exact integer geometry.
Full documentation, the constraint reference and benchmarks live at packvium.com.
Version 1.0.0 — the public API is frozen. Field names, status codes and the objective vector do not change without a major version, so any
1.xis a safe upgrade from any earlier1.x. Read docs/GUARANTEES.md before relying on a result.
pip install packviumfrom packvium import Container, Dimensions, Item, Packer, PackingConfig
result = Packer(PackingConfig.balanced()).pack(
items=[Item.create("book", Dimensions.mm("210", "140", "30"), quantity=4)],
containers=[Container.create("box", Dimensions.mm("400", "300", "250"))],
)
print(result.status) # feasible
for container in result.containers:
for placement in container.placements:
print(placement.item_id, placement.position, placement.orientation)Fractional inches are exact, not approximated:
Dimensions.inches("12 3/8", "8 1/2", "3/4")There is also a CLI that reads a JSON request on standard input:
echo '{"items":[{"id":"box","quantity":8,"dimensions":{"length":"50","width":"50","height":"50"}}],
"containers":[{"id":"carton","inner_dimensions":{"length":"100","width":"100","height":"100"}}]}' \
| python -m packviumRunnable, in examples/. Each one is a single file you can read top to bottom
and execute without a project around it. Every one of them is executed by the test suite
on each release, so none of them can quietly stop working.
New here? Read basic.py, then objectives.py — between them they cover what most
callers need. units.py and serialization.py explain the two design choices that
surprise people. extensions.py is last on purpose: reach for it only after the fields
in constraints.py have failed you.
| File | What it shows |
|---|---|
basic.py |
The smallest useful call: items in, placements out — and the three details in it that are easy to miss. |
objectives.py |
All six objectives on scenes where they genuinely disagree, including the rate card that makes the heavier shipment the cheaper one. |
constraints.py |
Upright-only, floor-only, non-stackable, top-load limits, and tags that keep two items out of the same box — plus how to read the reason an item was refused. |
units.py |
Why there are no floats anywhere: fractional inches, exact ticks, and the one-tick difference between a fit and a refusal. |
serialization.py |
The same request as JSON, the result in full, and exactly which mistakes are refused and which are silently ignored. |
shapes.py |
Items that are not their box: complementary wedges sharing one crate as convex_hull, and a cushion that compresses under load until the crush limit refuses it. |
nested.py |
Units into cartons, cartons onto a pallet, in one call. |
commerce.py |
Rate a shipment, apply an eligibility rule, and pin a catalog version. |
extensions.py |
A rule the schema has no field for — and an honest account of what you give up by writing one. |
PYTHONPATH=src python3 examples/objectives.py- Exact arithmetic. Length is measured in ticks of 1/16000 mm and weight in 1/8 µg. No coordinate is ever a float, so no placement decision depends on rounding.
- Real constraints. Weight and payload limits, permitted rotations, keep-upright, floor-only, non-stackable, top-load limits, minimum support ratio, tag incompatibility, clearance and rectangular obstacles.
- A solver portfolio, not one algorithm. Regular-grid, layer, extreme-point, maximal-space and bounded exact search, selected by problem shape and profile.
- Answers you can check. Every solution is re-validated by logic independent of the search. Unplaced items come back with a reason code, not silently missing.
- Deterministic. The same input and seed produce the same result, always.
- Multi-container and nested. Split across containers, or pack containers into containers.
- Extensible. Register your own constraints, item orderings, candidate scorers, container selectors or complete solvers.
| Document | Covers |
|---|---|
| docs/GUARANTEES.md | What is promised and what is not. Start here. |
| docs/PUBLIC-API.md | Inputs, outputs and status semantics. |
| docs/UNITS-AND-NUMERICS.md | Units, accepted input forms, rounding policy. |
Python 3.9 or newer. No dependencies.
One request and result contract, implemented independently in four engines (Rust, Python, PHP, JavaScript) and held to identical placements on a shared fixture set. Pick the package for your stack; mixing them in one system is safe.
Documentation, the constraint reference and the benchmarks are at packvium.com.
| Package | Install | Source |
|---|---|---|
Python — packvium |
pip install packvium |
packvium-python |
PHP — packvium/packvium |
composer require packvium/packvium |
packvium-php |
Rust — packvium |
packvium = "1.0" |
packvium-rust |
Node.js — @packvium/engine |
npm install @packvium/engine |
packvium-node |
Browser / WebAssembly — @packvium/browser |
npm install @packvium/browser |
packvium-wasm |
PHP FFI bridge — packvium/native-bridge |
composer require packvium/native-bridge |
packvium-php-bridge |
Python native selector — packvium-native |
from source until the native wheels ship | packvium-python-adapter |
See CONTRIBUTING.md. Security reports go through the process in SECURITY.md, not public issues.
MIT. See LICENSE.