pyczml
A Python library for building and parsing CZML (Cesium Language) documents.
CZML is a JSON format for describing time-dynamic 3D scenes in CesiumJS. This library provides a clean, type-safe Python API to create and manipulate CZML documents without writing raw JSON.
Installation
pip install pyczml
# or
uv add pyczml
Requires Python ≥ 3.11. Zero external dependencies.
Quick Start
from pyczml import CZMLDocument
doc = CZMLDocument()
p = doc.add_packet("satellite-1")
p.name = "Satellite 1"
p.position.cartographic_degrees = [116.39, 39.91, 0.0]
p.billboard.image = "https://example.com/pin.png"
p.billboard.color = [255, 0, 0, 255]
p.billboard.scale = 1.5
p.point.pixel_size = 10
p.point.color = [0, 255, 255, 255]
print(doc.to_json(indent=2))
Output:
[
{
"id": "satellite-1",
"name": "Satellite 1",
"position": {
"cartographicDegrees": [116.39, 39.91, 0.0]
},
"billboard": {
"image": "https://example.com/pin.png",
"scale": 1.5,
"color": { "rgba": [255, 0, 0, 255] }
},
"point": {
"pixelSize": 10,
"color": { "rgba": [0, 255, 255, 255] }
}
}
]
Core Concepts
Packet
A CZML document is a list of packets. Each packet represents a single object (satellite, aircraft, building, etc.) identified by a unique id. Packets can contain graphic properties like billboard, label, point, model, path, polygon, polyline, box, ellipse, ellipsoid, and position.
Document
CZMLDocument wraps the packet list and provides serialization:
doc = CZMLDocument()
p1 = doc.add_packet("obj-1")
p2 = doc.add_packet("obj-2")
print(doc.to_json())
Builder API
Property names follow snake_case conventions and are automatically translated to CZML's camelCase:
p.billboard.pixel_offset = [0, 50] # → pixelOffset
p.label.horizontal_origin = "LEFT" # → horizontalOrigin
Raw values (bool, int, float, str, list) are auto-wrapped into their CZML wrapper types:
p.billboard.show = True # → Boolean(boolean=True)
p.billboard.scale = 1.5 # → Double(number=1.5)
p.billboard.image = "img.png" # → Uri(uri="img.png")
p.billboard.color = [255,0,0,255] # → Color(rgba=[255,0,0,255])
Type System
CZML values are modeled as @dataclass types in pyczml.types.values. Each type is an InterpolatableProperty with first-class support for both shorthand and full dict forms.
| Category | Types |
|---|---|
| Primitives | Boolean, Double, Integer, String, Uri, Font |
| Enums | HorizontalOriginProp, VerticalOriginProp, LabelStyleProp, ArcTypeProp, etc. |
| Geometry | Color, Position, Orientation, EyeOffset, NearFarScalar, BoundingRectangle |
| Materials | SolidColorMaterial, ImageMaterial, GridMaterial, StripeMaterial, PolylineGlowMaterial |
| Graphics | Billboard, Label, Point, Model, Path, Polygon, Polyline, Ellipse, Ellipsoid, Box |
Examples
Position
# Cartographic (longitude, latitude, height in degrees)
p.position.cartographic_degrees = [116.39, 39.91, 0.0]
# Cartesian (x, y, z in meters)
p.position.cartesian = [1215000.0, -4736000.0, 4081600.0]
Color
from pyczml import Color
# RGBA (0-255)
p.billboard.color = [255, 0, 0, 255]
# RGBAf (0.0-1.0)
p.point.color = Color(rgbaf=[1.0, 0.0, 0.0, 1.0])
Material
from pyczml import SolidColorMaterial, Material
p.polygon.material = Material(
solidColor=SolidColorMaterial(color=Color(rgba=[0, 255, 0, 128]))
)
Time Intervals and Availability
from pyczml import time_interval, to_iso8601
from datetime import datetime, timezone
# Set object availability to a time range
p.availability = time_interval(
datetime(2024, 1, 1, tzinfo=timezone.utc),
datetime(2024, 12, 31, tzinfo=timezone.utc),
)
print(p.availability) # "2024-01-01T00:00:00Z/2024-12-31T00:00:00Z"
References
from pyczml import ref
# Build a reference string: "Satellite/billboard/image"
r = ref("Satellite", "billboard", "image")
# Local reference (same document): "#target/position"
r = ref("target", "position", local=True)
# Use in a CZML property
p.billboard.image = r # shorthand → Uri(reference=ref("..."))
Loading Existing CZML
doc = CZMLDocument.load("scene.czml") # from file
# or
doc = CZMLDocument.loads(json_string) # from string
p = doc.packets[0]
print(p.id) # reads from parsed data
print(p.billboard.color) # Color(rgba=[...])
# Modify and re-export
p.billboard.scale = 2.0
print(doc.to_json(indent=2))
Full Roundtrip
from pyczml import CZMLDocument
doc = CZMLDocument()
p = doc.add_packet("bird")
p.position.cartographic_degrees = [120.0, 30.0, 1000.0]
p.model.gltf = "https://example.com/bird.glb"
p.model.scale = 1.0
json_str = doc.to_json()
loaded = CZMLDocument.loads(json_str)
assert loaded.packets[0].id == "bird"
API Overview
CZMLDocument
| Method | Description |
|---|---|
add_packet(id) |
Create and append a new packet |
to_json(indent) |
Serialize to JSON string |
loads(json_str) |
Deserialize from JSON string |
load(path) |
Deserialize from JSON file |
packets |
List of CZMLPacket |
CZMLPacket
| Property | Type | Description |
|---|---|---|
id |
str |
Unique object identifier |
name |
str |
Display name |
delete |
bool |
Delete this packet |
parent |
str |
Parent object ID |
version |
str |
Version string |
availability |
str |
Time interval string |
position |
builder | Position |
billboard |
builder | Billboard graphic |
label |
builder | Label graphic |
point |
builder | Point graphic |
model |
builder | 3D model graphic |
path |
builder | Path graphic |
polygon |
builder | Polygon graphic |
polyline |
builder | Polyline graphic |
box |
ellipse |
ellipsoid |
Helper Functions
| Function | Description |
|---|---|
ref(object_id, *properties, local=False) |
Build CZML reference string |
to_iso8601(dt=None) |
Convert datetime to ISO 8601 string |
time_interval(start, end) |
Build CZML time interval string |
License
Apache 2.0
Metadata
Release files for pyczml 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| pyczml-0.1.0.tar.gz | 35.7 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pyczml-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 56.6 kB
Release files / pyczml-0.1.0.tar.gz
| Download URL | pyczml-0.1.0.tar.gz |
|---|---|
| Size | 35.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7af4a27015871687c7369ed7fd9ba89d46e94297c36ec445e2aa379f855fa927
|
|
BLAKE2b-256 checksum How to use checksums |
718a2668de7c609f96996d4c6ea3d454aeae6fffefe738c16352e3fa4d9cb58d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.12 {"installer":{"name":"uv","version":"0.11.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / pyczml-0.1.0-py3-none-any.whl
| Download URL | pyczml-0.1.0-py3-none-any.whl |
|---|---|
| Size | 20.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
021a625765e2d969c80f159e9c3f7606ea7f46130de0b433f2a0608d986d752f
|
|
BLAKE2b-256 checksum How to use checksums |
607ab0d8ad192313442009c6bde409c9917a5cdd15f6acdb378ceca6cbb83d8b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.12 {"installer":{"name":"uv","version":"0.11.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for pyczml 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.