Contributing notes¶
This document is a work in progress.
Management commands¶
We use the just tool for all management commands.
The commands are implemented in justfile
.
Branches¶
- The
main
branch is reserved to stable releases. - Development occurs in the
dev
branch.
Python bindings¶
Datoviz provides two layers of Python bindings:
- Low-level bindings — Automatically generated
ctypes
wrappers for the C API. - High-level Pythonic API — A more user-friendly layer built on top of the raw bindings.
Low-level ctypes bindings¶
The low-level bindings are automatically generated from the C headers and written to datoviz/_ctypes_.py
. This file is committed to the repository but should not be edited manually.
The C header files are parsed by tools/parse_headers.py
, which outputs a structured representation to build/headers.json
. This JSON file serves as the source for both:
- The generation of the
ctypes
Python bindings. - The generation of the C API documentation.
C functions such as dvz_function()
are exposed in Python as dvz.function()
(after import datoviz as dvz
).
C enums like DVZ_MYENUM
become dvz.MYENUM
in Python.
This layer is a nearly 1:1 mapping of the C API, useful for advanced users or debugging.
High-level Pythonic API¶
Since version v0.3, Datoviz also includes a more idiomatic Python API built on top of the ctypes
layer. This API offers simplified, object-oriented access to Datoviz functionality.
For example:
import datoviz as dvz
app = dvz.App()
fig = app.figure()
panel = fig.panel()
marker = app.marker(...)
panel.add(marker)
app.run()
This Pythonic layer abstracts away many of the lower-level details while retaining full performance and flexibility. It is the recommended entry point for most Python users.
Documentation and examples are being expanded as the API evolves.
Continuous integration/continuous delivery¶
GitHub Actions-based CI/CD is not yet active in this repository. In the near future, we intend to activate it for:
- cross-platform automated testing of the C library and Python bindings ;
- automated build of the Python wheels on all supported platforms ;
- automated build of the documentation and gallery.
Debugging¶
Console logging¶
You can control the verbosity of Datoviz's console output by setting the DVZ_LOG_LEVEL
environment variable:
DVZ_LOG_LEVEL=2
— Info level (default)DVZ_LOG_LEVEL=1
— Debug levelDVZ_LOG_LEVEL=0
— Trace level (very verbose; use with caution)
Datoviz Intermediate Protocol requests¶
Datoviz user-facing commands generate an internal stream of rendering requests, which are processed in real time by the Vulkan renderer. For debugging, you can inspect these requests to determine whether issues originate in the high-level code (which builds the requests) or in the low-level renderer (less common).
To print a YAML representation of the generated requests to standard output, set:
DVZ_VERBOSE=prt
Screenshot capture¶
To render all Datoviz applications offscreen and save a screenshot, set:
DVZ_CAPTURE_PNG=path/to/image.png
— Saves the rendered figure to a PNG file.
Performance monitoring¶
Set the following environment variables to enable performance-related diagnostics:
DVZ_FPS=1
— Display an FPS (frames per second) counter.DVZ_MONITOR=1
— Show a GPU memory monitor (allocated memory usage).
Note
The current FPS computation is suboptimal and may not reflect true frame rate. Improvements are planned — contributions are welcome!
Styling Guide¶
This section provides guidelines for maintaining consistent code style in the Datoviz project, for both C source code and the Python wrapper. Consistency helps readability and maintainability. Most formatting is automatically handled by tools.
C Code Style¶
Code Formatting¶
- Automatic formatting: We use
clang-format
with a custom configuration. The.clang-format
file is located at the root of the repository. - Auto-format on save: It is assumed that your IDE or editor is configured to automatically format C/C++ files on save using this configuration.
Additional conventions¶
- Use comment banners (
/*****...*****/
) to clearly separate sections. - Group includes and sort them logically: system headers, followed by local headers.
- Use
ANN(ptr)
(assert not null) for pointer assertions andASSERT(condition)
for general assertions. - Keep function definitions short and readable; use blocks and whitespace to visually separate logic when helpful.
- Prefer function names with consistent prefixes (e.g.,
dvz_axes_resize
,dvz_demo_panel_3D
). - Avoid trailing whitespace and excessive blank lines (more than 3 is trimmed by clang-format).
Python Wrapper Style¶
Code Formatting and Linting¶
- We use Ruff for linting and formatting.
- The configuration is in
pyproject.toml
. - Python files should be auto-formatted and linted using
ruff format
andruff check
.
Additional conventions¶
- Use PEP8 naming and structure wherever possible.
- Keep line length ≤ 99 characters.
- Docstrings should follow NumPy-style (
""" """
) format, withParameters
,Returns
, etc. - Prefer
assert
for internal sanity checks in constructors. - Type hints should be used consistently, including in attribute declarations.
- Wrap class-level attributes with type annotations (e.g.,
c_axes: dvz.DvzAxes = None
). - Group code sections using banners and comments (e.g.,
# Axes
,# ----...----
). - Avoid complex logic in wrapper code; keep it minimal and declarative.