fluida-core
A framework-agnostic, pure-Python container layout engine. Computes how many columns and rows to use, and what size each cell should be, from a real container size and a known item count.
Status: pre-release, 0.2.0. Not published to PyPI yet.
This is an independent Python port of the same algorithm implemented in @fluida/core (TypeScript) — not a wrapper around it. No JavaScript, Node.js, subprocess, or browser is involved anywhere in this package. Both implementations are checked against the same shared, language-neutral test cases in spec/conformance/layout-cases.json, at the root of the Fluida monorepo.
Installation
Not available on PyPI yet.
pip install -e path/to/fluida-core
Quick example
from fluida_core import compute_container_layout
result = compute_container_layout(
container_width=1200,
container_height=600,
item_count=6,
gap=16,
min_item_width=280,
strategy="fit",
)
print(result)
# LayoutResult(columns=4, rows=2, cell_width=288.0, cell_height=288.0)
API
compute_container_layout(container_width, container_height, item_count, strategy="fit", gap=16, aspect_ratio=1, min_item_width=None)
container_width— the container's real measured width. Must be finite and>= 0;0is valid and represents a container not yet measured.container_height— the container's real measured height, orNonefor auto-height (see below). When provided, must be finite and>= 0.item_count— how many cells to lay out. Must be a positive integer —1.5,True/False(boolis anintsubclass in Python, rejected explicitly),NaN, andInfinityall raiseFluidaConfigError.strategy— one of"fit","fill","balanced","preserve-ratio". Anything else raisesFluidaConfigError. Defaults to"fit".gap— space between cells. Defaults to16.aspect_ratio— width / height. Only used by"preserve-ratio". Defaults to1.min_item_width— when set, column counts whose resulting cell would be narrower than this are excluded entirely.None(the default) applies no such constraint.
Returns a LayoutResult:
@dataclass(frozen=True)
class LayoutResult:
columns: int
rows: int
cell_width: float
cell_height: float
Raises FluidaConfigError (a ValueError subclass) for an invalid item_count, gap, aspect_ratio, min_item_width, container_width, container_height, or strategy — the same conditions the TypeScript implementation raises FluidaConfigError for.
Strategies
fit(default) — square cells, the largest size that fits without overflow. Choose it for uniform, icon-like content.fill— uses 100% of the space in both axes; cells may not be square. Requires a knowncontainer_height.balanced— the smaller offill's two dimensions stays unchanged; the larger is pulled toward it (geometric mean with the smaller) without ever exceeding either original dimension — less distorted thanfill, without forcing a square likefit. Requires a knowncontainer_height.preserve-ratio— cells keep the configuredaspect_ratioexactly, even if that leaves leftover space. Choose it for charts, images, or video.
Auto-height
container_height can be None for fit and preserve-ratio specifically, and only when min_item_width is also set:
result = compute_container_layout(
container_width=800,
container_height=None,
item_count=4,
strategy="preserve-ratio",
aspect_ratio=4 / 3,
min_item_width=300,
)
Without a known height, column count comes from min_item_width alone, and cell_height is derived from the resulting cell_width directly. fill and balanced cannot do this — both raise FluidaConfigError if container_height is omitted, as does fit/preserve-ratio without min_item_width also set.
What this package does not do
It does not measure anything — there is no DOM, no browser, no ResizeObserver here. It takes numbers you already have and returns a layout. Measuring a real container in a browser is dash-fluida's job, or your own application's, if you're using this package directly for offline calculations, backend logic, or generating previews.
Compatibility
Python >=3.9. No runtime dependencies. Fully type-hinted; ships a py.typed marker.
Conformance with the TypeScript implementation
tests/test_conformance.py loads spec/conformance/layout-cases.json directly — the same file @fluida/core's own TypeScript test suite checks against — and verifies this package produces the same columns/rows (exact equality) and cell_width/cell_height (within the tolerance the file itself declares). This is meant to catch real behavioral drift between the two implementations, not to prove they're bit-identical: floating-point arithmetic across two different language runtimes isn't expected to match beyond a small tolerance, and the shared file says so explicitly.
Development
python -m venv .venv
.venv/bin/pip install -e ".[dev]"
.venv/bin/python -m pytest
License
MIT.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fluida_core-0.2.3.tar.gz.
File metadata
- Download URL: fluida_core-0.2.3.tar.gz
- Upload date:
- Size: 12.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
06720e2822a9429ffa58fa5d8ff2cee02f65b54c714a0032eeefb83c54a65178
|
|
| MD5 |
b58954a54e7a7ad8df1c2eb72571f63a
|
|
| BLAKE2b-256 |
10ab4ebe1d167e7c7ca4b39334ee9b5492466008c9f0ca472aa081621ae36db6
|
File details
Details for the file fluida_core-0.2.3-py3-none-any.whl.
File metadata
- Download URL: fluida_core-0.2.3-py3-none-any.whl
- Upload date:
- Size: 8.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
98c88645e07f4c730ce7eee642cf98624ab452033ed769af42d06ddd173aec22
|
|
| MD5 |
0e43582837d99f3978132fba4e00bcc1
|
|
| BLAKE2b-256 |
a8f746028e79af457401612b839e5dbbe059b6d0a2bf9305a260a691ff5ae1af
|