Floorplans¶
A floorplan is an image — PNG, SVG, or PDF — bound to a sublocation
(area). The SDK exposes full CRUD plus an download_image helper for
fetching the stored bytes back.
Wire shape (probed from the live server)¶
The server's createFloorplan schema requires:
sublocation_uid(string)image: {original_filename: string, file: <base64>}(object, both keys required)
Optional: display_name, image_scale, image_rotation,
image_offset_x, image_offset_y.
There is no name field on floorplans — use display_name for the
user-facing label.
Imageless floorplans are not permitted — the server rejects creates without an image with HTTP 422.
Create — from in-memory bytes¶
with open("warehouse.png", "rb") as fh:
plan = client.floorplans.create(
sublocation_uid=area.uid,
image_bytes=fh.read(),
original_filename="warehouse.png",
)
print(plan.uid, plan.url)
Create — from a path¶
The SDK reads the file and derives original_filename from the path's
basename:
plan = client.floorplans.create(
sublocation_uid=area.uid,
image_path="warehouse.png",
display_name="Warehouse 12 — Bay 3",
)
image_bytes/original_filename and image_path are mutually
exclusive — pass one or the other, not both. Neither raises
ValueError before any HTTP call (it would be rejected anyway).
Update — image optional¶
floorplans.update(uid, …) only sends the fields you pass. To keep the
stored image and change only metadata:
To replace the image, pass new image input:
Delete¶
The server removes both the metadata row and the stored image file.
A subsequent GET of the URL returns 404.
Download the image¶
download_image accepts either a Floorplan instance (uses its
.url) or a uid (calls get(uid) first to resolve):
data = client.floorplans.download_image(plan)
with open("downloaded.png", "wb") as fh:
fh.write(data)
For very large files (production floorplans can be tens of MB of PDF), stream directly to disk:
stream_to= returns None; the file is written incrementally with a
64 KB chunk size. The read timeout is automatically extended to
180 seconds for the image GET — matches the desktop site-plan
client's Network::Timeout::Resource.
Log redaction note¶
Image payloads (base64-encoded) can be tens of KB to MB. The SDK's
redaction filter automatically truncates any logged string longer than
1024 chars to <truncated N bytes>, keeping DEBUG logs readable when
you ask for them. Your actual image data is never logged in plain
text. See Security for the full redaction
guarantee.
Server-side re-encoding¶
The live server re-encodes PNG uploads on storage (likely to normalize / compress). Downloaded bytes are NOT byte-identical to uploaded bytes, but the dimensions and image content are preserved. Tests that need to verify "the image was replaced" should distinguish by width/height, not by byte equality.