# This pyproject.toml defines the uv workspace for Python development. # # Pixi (pixi.toml) manages build tools, while uv uses this file to manage # Python runtime dependencies in a .venv directory. The two work together: # # pixi run py-build # Uses maturin to build rerun-sdk into .venv # pixi run uv run … # Runs Python scripts using .venv # # Workspace members (rerun_py, rerun_notebook, examples) are defined in # [tool.uv.workspace] below. [project] name = "rerun-workspace" version = "0.28.0-alpha.1+dev" description = "Rerun Python workspace" requires-python = ">=3.10,<3.13" [dependency-groups] dev = [ # NOTE: we leave `rerun-sdk` and `rerun-notebook` out of the basic dev dependency list. # This is because they can be slow to build in a clean environment and it's useful to # be able to run tools like linting, etc. without having built all the bindings. # # This fixup package installs a .pth file that makes `import rerun` work # with editable installs by adding rerun_py/rerun_sdk to the Python path. "rerun-dev-fixup", "opentelemetry-exporter-otlp-proto-grpc==1.39.0", "maturin>=1.0.0", "ruff==0.15.7", "mypy==1.19.1", "nbqa==1.9.1", # Packages needed for running scripts + their type stubs for mypy "pandas>=2.0", "pandas-stubs==2.3.3.251201", "requests>=2.28", "types-requests==2.32.4.20250913", "tqdm>=4.60", "ty==0.0.31", "types-tqdm==4.67.0.20250809", "colorama>=0.4", "types-colorama>=0.4.15", "Pillow>=12.2.0,<13", # has py.typed, no stubs needed "types-psutil>=7.0", # Stubs for `psutil`, used by `rerun.tracing_session()`. # Typed packages needed for linting scripts/examples "attrs>=23.1.0", "semver>=3.0,<3.1", "tomlkit>=0.12", "GitPython>=3.1", "PyGithub>=2.0", #NOLINT "Jinja2>=3.1", "rich>=13.0", # Testing packages (typed, needed for linting tests) "pytest>=8.0", "pytest-benchmark", "inline-snapshot>=0.31", "syrupy>=4.0", # Notebook dependencies (needed for linting rerun_notebook) "anywidget>=0.9", "jupyter-ui-poll>=0.2", "ipywidgets>=8.0", # Example dependencies (needed for linting examples) "platformdirs>=4.0", # Script dependencies (needed for linting scripts) "google-cloud-storage>=2.9.0", "google-cloud-compute>=1.20.0", "pyyaml>=6.0", "types-pyyaml>=6.0", "wheel>=0.46", # Needed by lerobot importer example "huggingface-hub<1.0", # Typed packages for dataframe/arrow operations (needed for linting examples/tests) "polars>=1.0", "datafusion>=53.0", "jupyter>=1.0", "types-protobuf", # Needed by mcap-protobuf-support # Needed for pretty-printing tables in `fetch_patch_candidates.py` "tabulate>=0.9.0", "types-tabulate>=0.9.0", ] snippets = ["rerun-sdk[dataloader]", "av", "pandas", "mcap-protobuf-support"] examples = [ # External deps used by examples "polars>=0.12.0", "opencv-python>=4.6", "segment-anything @ git+https://github.com/facebookresearch/segment-anything.git", "torch>=2.5.1", # require at least 2.5.1 for some examples "torchvision>=0.20.1", # require at least 0.20.1 for some examples # lerobot (used by the dataloader example) is not listed here because it # requires Python >=3.12 while this workspace supports 3.10+. The dataloader # is an isolated uv project — sync it from its own directory. # Example packages from workspace "air_traffic_data", "animated_urdf", "any_scalar", "arkit_scenes", "blueprint", "blueprint_stocks", "camera_video_stream", "clock", "controlnet", "dataframe_query", "detect_and_track_objects", "dicom_mri", "dna", "drone_lidar", "graph_lattice", "graphs", "imu_signals", "incremental_logging", "lidar", "live_camera_edge_detection", "live_scrolling_plot", "llm_embedding_ner", "log_file", "minimal", "minimal_options", "multiprocess_logging", "multithreading", "nuscenes_dataset", "nv12", "objectron", "open_photogrammetry_format", "openstreetmap_data", "plots", "raw_mesh", "rgbd", "robot_data_preprocessing", "rrt_star", "segment_anything_model", "server_tables", "shared_recording", "stdio", "structure_from_motion", "using_index_values", # TODO(RR-3223): fix opentelemetry conflicts # "face_tracking", # "gesture_detection", # "human_pose_tracking", ] docs = [ # Documentation build dependencies (mkdocs and plugins) "griffe>=1.14,<2", "griffe-public-redundant-aliases==0.3.0", "griffe-warnings-deprecated==1.1.0", "mkdocs==1.6.1", "mkdocs-gen-files==0.5.0", "mkdocs-literate-nav==0.6.1", "mkdocs-redirects==1.2.2", "mkdocs-material==9.4.7", "mkdocs-material-extensions==1.3", "mkdocstrings>=0.28.2,<0.29", "mkdocstrings-python>=1.16.2,<2", "pygments", "setuptools>75", "sphobjinv==2.3.1", ] [tool.uv] package = false # pyarrow 24.0.0 ships an incomplete `py.typed` that breaks mypy on `pyarrow.compute.*`. # 23.x has no type stubs (so mypy leaves it untyped) and clears RUSTSEC/GHSA pyarrow alert >= 23.0.1. constraint-dependencies = ["pyarrow>=23.0.1,<24"] [tool.uv.sources] rerun-sdk = { workspace = true } rerun-notebook = { workspace = true } rerun-dev-fixup = { path = "rerun_py/rerun_dev_fixup", editable = false } # Example packages air_traffic_data = { workspace = true } animated_urdf = { workspace = true } any_scalar = { workspace = true } arkit_scenes = { workspace = true } blueprint = { workspace = true } blueprint_stocks = { workspace = true } camera_video_stream = { workspace = true } clock = { workspace = true } controlnet = { workspace = true } dataframe_query = { workspace = true } detect_and_track_objects = { workspace = true } dicom_mri = { workspace = true } dna = { workspace = true } drone_lidar = { workspace = true } # face_tracking = { workspace = true } # gesture_detection = { workspace = true } graph_lattice = { workspace = true } graphs = { workspace = true } # human_pose_tracking = { workspace = true } imu_signals = { workspace = true } incremental_logging = { workspace = true } lidar = { workspace = true } live_camera_edge_detection = { workspace = true } live_scrolling_plot = { workspace = true } llm_embedding_ner = { workspace = true } log_file = { workspace = true } minimal = { workspace = true } minimal_options = { workspace = true } multiprocess_logging = { workspace = true } multithreading = { workspace = true } nuscenes_dataset = { workspace = true } nv12 = { workspace = true } objectron = { workspace = true } open_photogrammetry_format = { workspace = true } openstreetmap_data = { workspace = true } # TODO(RR-3548): Figure out a way to include this, without lerobot causing dependency issues. # dataloader = { workspace = true } # Excluded: lerobot requires Python >=3.12. plots = { workspace = true } raw_mesh = { workspace = true } rgbd = { workspace = true } robot_data_preprocessing = { workspace = true } rrt_star = { workspace = true } segment_anything_model = { workspace = true } server_tables = { workspace = true } shared_recording = { workspace = true } stdio = { workspace = true } structure_from_motion = { workspace = true } using_index_values = { workspace = true } [tool.uv.workspace] members = [ "rerun_py", "rerun_notebook", # Examples "examples/python/air_traffic_data", "examples/python/animated_urdf", "examples/python/any_scalar", "examples/python/arkit_scenes", "examples/python/blueprint_stocks", "examples/python/blueprint", "examples/python/camera_video_stream", "examples/python/clock", "examples/python/controlnet", "examples/python/dataframe_query", "examples/python/depth_guided_stable_diffusion", "examples/python/detect_and_track_objects", "examples/python/dicom_mri", "examples/python/dna", "examples/python/drone_lidar", # "examples/python/face_tracking", # "examples/python/gesture_detection", "examples/python/graph_lattice", "examples/python/graphs", "examples/python/table_grid_with_flags", # "examples/python/human_pose_tracking", "examples/python/imu_signals", "examples/python/incremental_logging", "examples/python/lidar", "examples/python/live_camera_edge_detection", # "examples/python/live_depth_sensor", # Excluded: requires Python <3.11 "examples/python/live_scrolling_plot", "examples/python/llm_embedding_ner", "examples/python/log_file", "examples/python/minimal", "examples/python/minimal_options", "examples/python/multiprocess_logging", "examples/python/multithreading", "examples/python/nuscenes_dataset", "examples/python/nv12", "examples/python/objectron", # "examples/python/ocr", # Excluded: paddleclas has incompatible opencv requirements "examples/python/open_photogrammetry_format", "examples/python/openstreetmap_data", # "examples/python/dataloader" # Excluded: RR-3548 (lerobot requires Python >=3.12). "examples/python/plots", "examples/python/raw_mesh", "examples/python/rgbd", "examples/python/robot_data_preprocessing", "examples/python/rrt_star", "examples/python/segment_anything_model", "examples/python/server_tables", "examples/python/shared_recording", "examples/python/stdio", "examples/python/structure_from_motion", "examples/python/table_blueprints", "examples/python/table_zoo", "examples/python/template", "examples/python/using_index_values", ] [tool.ruff] line-length = 120 preview = true src = ["rerun_py", "rerun_py/rerun_sdk", "rerun_notebook"] extend-exclude = [ "crates", "target", ".venv", # Automatically generated test artifacts "target_ra/", "target_wasm/", "target/", "venv/", "scripts/ci/compare_path_digest.py", # Intentionally uses ''' instead of """ so we can embed it in a docstring in the Python API docs. "docs/snippets/all/archetypes/text_document.py", "docs/snippets/all/views/text_document.py", # TODO(#4047): incomplete example snippet "docs/snippets/all/tutorials/timelines_example.py", # Intentionally incomplete snippets "docs/snippets/all/concepts/how_helix_was_logged.py", "docs/snippets/all/concepts/static", "docs/snippets/all/tutorials/custom-application-id.py", "docs/snippets/all/tutorials/custom-recording-id.py", # generated "examples/python/objectron/objectron/proto/objectron/proto.py", # Copied from https://github.com/huggingface/diffusers/blob/fc9fecc217e58d72c0d5796575c72088251ff4df/src/diffusers/pipelines/stable_diffusion/pipeline_stable_diffusion_depth2img.py "examples/python/depth_guided_stable_diffusion/depth_guided_stable_diffusion/huggingface_pipeline.py", # Copied from https://github.com/colmap/colmap/blob/bf3e19140f491c3042bfd85b7192ef7d249808ec/scripts/python/read_write_model.py "examples/python/structure_from_motion/structure_from_motion/read_write_model.py", ] [tool.ruff.lint] ignore = [ # Rules that became active with the ruff upgrade to 0.15: # TODO(emilk): enable more of these "B005", # Using `.strip()` with multi-character strings "BLE001", # Do not catch blind exception: `Exception` "DTZ001", # `datetime.datetime()` called without a `tzinfo` argument "DTZ002", # `datetime.datetime.today()` used "DTZ005", # `datetime.datetime.now()` called without a `tz` argument "DTZ006", # `datetime.fromtimestamp()` called without a `tz` argument "DTZ007", # `datetime.strptime()` without `%z` "LOG015", # Root logger call "PLR1704", # Redefining argument with the local name "PLW0602", # Using global for variable that is not assigned "PLW1510", # `subprocess.run` without explicit `check` argument "RUF012", # Mutable class variables should be annotated with `typing.ClassVar` "S110", # `try`-`except`-`pass` detected "SIM102", # Use a single `if` statement instead of nested `if` statements "SIM115", # Use context handler for opening files "TRY002", # Create your own exception "TRY004", # Prefer `TypeError` exception for invalid type ] [tool.ruff.lint.per-file-ignores] "docs/snippets/all/*" = [ # Missing required import: `from __future__ import annotations` "I002", ] "crates/viewer/re_viewer/data/quick_start_guides/*" = [ # Missing required import: `from __future__ import annotations` "I002", ] "tests/python/*" = [ # We don't care about nice APIs in our tests: "PLR0917", ] "examples/notebook/notebook_neural_field_2d/neural_field_2d.ipynb" = [ # Intentional use of `σ` "RUF001", ] "examples/*" = [ # We don't care about nice APIs in our examples: "PLR0917", ] "scripts/*" = [ # We don't care about nice APIs in our scripts: "PLR0917", ] ###################### # mypy configuration # ###################### [tool.mypy] # Force mypy to check against 3.10 stdlib, even though pixi runs 3.11. # This catches imports like `from typing import Self` that don't exist in 3.10. python_version = "3.10" # Examples and docs are managed independently of the SDK. # in ini file adjacent to this. files = [ "rerun_py/rerun_sdk/rerun", "rerun_py/rerun_bindings", "rerun_py/tests", "rerun_notebook/src/rerun_notebook", "tests/python", ] # These paths allow mypy to find rerun and rerun_bindings without needing # to run maturin develop first (which installs the .pth file). mypy_path = ["rerun_py", "rerun_py/rerun_sdk"] namespace_packages = true show_error_codes = true strict = true enable_error_code = ["redundant-expr", "truthy-bool", "ignore-without-code", "possibly-undefined"] ignore_missing_imports = false no_implicit_reexport = false disallow_untyped_calls = false [[tool.mypy.overrides]] module = [ "pyarrow.*", # https://github.com/jupyter-widgets/ipywidgets/issues/3688 "ipywidgets.*", "anywidget.*", # TODO(nick): is this blocked on above? "jupyter_ui_poll.*", # Ignore imports used in tests but not in the SDK. "torch.*", "torchvision.*", "torchaudio.*", "cv2.*", "huggingface_hub.*", ] ignore_missing_imports = true [[tool.mypy.overrides]] # rerun_draft is a sandbox for testing new APIs - we don't care about strict type checking module = ["api_sandbox.rerun_draft.*", "rerun_draft.*"] ignore_errors = true ignore_missing_imports = true [tool.ty.environment] extra-paths = ["rerun_py", "rerun_py/rerun_sdk"] [tool.ty.src] include = [ "rerun_py/rerun_sdk/rerun", "rerun_py/rerun_bindings", "rerun_py/tests", "rerun_notebook/src/rerun_notebook", "tests/python", ] [tool.ty.rules] # parsing disagrees with mypy unused-ignore-comment = "ignore" unused-type-ignore-comment = "ignore" # Stricter parsing than mypy invalid-argument-type = "ignore" # this is our api draft need to figure out that config unresolved-import = "ignore" # others to burn down call-non-callable = "ignore" # TODO(astral-sh/ty/#2501) index-out-of-bounds = "ignore" invalid-assignment = "ignore" no-matching-overload = "ignore" unresolved-attribute = "ignore" unresolved-reference = "ignore" unsupported-operator = "ignore"