This guide helps AI coding agents make high-quality, repo-aligned changes to PyDynamicReporting, which is the Python client library for Ansys Dynamic Reporting. It focuses on how this repository is wired (tooling, structure, conventions) so agents can work quickly without breaking CI. Read through it carefully before making changes. Read the README, especially the development setup section, for additional context.
When you change code in this repo, aim to always:
- Preserve user-facing APIs and keep changes backwards compatible unless the app or API is unreleased or the user explicitly approves a breaking change.
- Add or update tests for behavior changes (at least: happy path + 1 edge case).
- Keep tests separate from production code in dedicated test files or test folders.
- Run focused verification before concluding and after every commit:
make check(lockfile consistency + pre-commit)make smoketest(fast import sanity check)- focused tests for the changed behavior
- Do not run full test suites by default. Run
make testonly when explicitly requested or after confirming that the change is broad enough to require it. - After every commit, activate the project virtual environment, run
uv sync --upgrade --all-extrasanduv lock --upgrade, and commit any resultinguv.lockupdate so CISecurity Scanchecks do not fail. - Avoid unrelated reformatting and keep diffs tight.
PyDynamicReporting is the Python client library for Ansys Dynamic Reporting (formerly documented as Nexus). It provides a Pythonic interface for pushing items (images, text, 3D scenes, tables, etc.) into a reporting database and creating dynamic reports.
- Repository: https://github.com/ansys/pydynamicreporting
- Documentation: https://dynamicreporting.docs.pyansys.com/
- Package:
ansys-dynamicreporting-coreon PyPI - Python support: 3.10–3.13 (
requires-python = ">=3.10, <3.14") - License: MIT
├── src/ansys/dynamicreporting/core/ # Main package
│ ├── adr_item.py # Item management (generated in some workflows)
│ ├── adr_report.py # Report objects
│ ├── adr_service.py # Service interface
│ ├── docker_support.py # Docker integration
│ ├── serverless/ # Serverless implementation
│ └── utils/ # Additional utilities
├── tests/ # Pytest suite
├── doc/ # Sphinx docs
├── codegen/ # Code-generation/build hooks
├── default_templates/ # Report templates
└── scripts/ # Dev/release helper scripts
Notes:
- Some files (notably
adr_item.py,adr_utils.py, andbuild_info.py) may be generated via build hooks / codegen. Avoid hand-editing those unless you’re intentionally changing generation inputs.
This repo uses uv + a checked-in lockfile (uv.lock). The Makefile wraps the canonical workflows.
- Python 3.10, 3.11, 3.12, or 3.13
uvmake(on Windows,make installuses Git Bash under the hood)
make installWhat it does:
uv sync --frozen --all-extras(reproducible env fromuv.lock)- installs the package in editable mode
If you’re not using make, the equivalent is:
uv sync --frozen --all-extras
uv run python -m pip install -e .- Black with line length 100 (see
[tool.black]inpyproject.toml) - isort with Black profile and line length 100
- CI style checks are enforced via pre-commit
Run the repo’s style gate:
make checkUse NumPy-style docstrings for public APIs and non-trivial internals.
If you touch a file that is generated by codegen/ or the build hook, prefer:
- finding the source-of-truth input in
codegen/, - updating that input,
- regenerating/bumping in the standard workflow.
- Add concise comments where code would otherwise require careful reading to understand the intent.
- Add more detailed comments for non-trivial algorithms, domain-specific behavior, performance tradeoffs, compatibility decisions, or intentionally unusual code.
- Keep comments accurate and useful. Cleaning up stale, misleading, or redundant comments is encouraged.
- Do not add comments that merely repeat what the next line of code says.
- Reuse existing helpers, patterns, and abstractions wherever possible. Keep changes DRY.
- Follow separation of concerns and the single responsibility principle.
- Do not change, refactor, or reformat unrelated code unless it is absolutely necessary for the requested change. Suggestions to improve surrounding code are welcome, but keep them separate from the implementation unless approved.
- Keep UI changes local to UI code only, and match the existing UI style guidelines and conventions.
- Consider algorithmic time complexity and space complexity before choosing an implementation.
- Avoid brute-force approaches, unnecessary quadratic operations, and avoidable repeated work when a clearer scalable option exists.
- Prefer readable code over overly complicated optimizations when the performance benefit is not material.
- If a requested change would make performance worse, stop before implementing it and explain the tradeoff clearly, with enough detail for a junior developer to understand.
- Do not add third-party libraries without explicit approval.
- Ground all development work involving libraries in official documentation. Do not assume library behavior when documentation can be checked.
- Use normal imports and public APIs. Do not load source files as blobs and execute them inside another block of code.
- Do not use time-based waiting hacks, such as arbitrary sleeps, to make tests or workflows pass.
- Do not add hacky retry loops. If retries are truly needed, use an existing repo pattern or a bounded, well-justified mechanism.
- Use correct, specific types when adding or changing type annotations.
- Do not use filler generic types, broad
Any,type: ignore, or temporary placeholder types just to satisfy CI. - Do not add casts, such as
typing.cast, only to silence type checkers without fixing the underlying typing issue.
- If there are open questions, insufficient context, tool or merge conflicts, or a decision cannot be made confidently, do not make assumptions. Stop, ask for confirmation, and proceed only after receiving it.
The repo uses pytest.
- Fast sanity check:
make smoketest- Focused tests for changed behavior:
uv run pytest path/to/test_file.py -q- Full test suite with coverage, only when explicitly requested or after confirming it is needed:
make testTips for good tests in this repo:
- Favor unit tests by default; gate truly external dependencies behind markers.
- Keep test code in separate test files or test folders. Do not commingle tests with production code.
- Use existing fixtures in
tests/conftest.pyandtests/serverless/conftest.py. - Keep test data in
tests/test_data/(ortests/serverless/test_data/when appropriate). - The tests require an installation of the flagship package through a Docker image followed by both running the image as a container(service setup) and extracting the required files from the image (serverless setup). Check CI configuration under .github/workflows/ci_cd.yml and existing tests for examples.
Direct commits to main aren’t allowed.
Recommended prefixes (matches CONTRIBUTING.md):
fix/*– bug fixes and small patchesfeat/*– new featuresdoc/*– documentation-only changesmaint/*– maintenance/CItesting/*– test changesjunk/*– experimental workno-ci/*– low-impact work that shouldn’t trigger CIrelease/*– release-related work
The authoritative dependency list is in pyproject.toml.
Highlights:
requests,docker,Pillow- Serverless stack:
django,djangorestframework,django-guardian,psycopg[binary] - Data/analytics:
numpy,pandas,statsmodels - Export/rendering:
python-pptx,weasyprint,django-weasyprint
- Find the public surface impacted (imports, docs, examples).
- Search for existing helpers and patterns before adding new ones.
- Identify whether the change is core, serverless, docker, or docs.
- For changes involving external libraries, verify behavior against official documentation before implementing.
- Keep changes local.
- Don’t refactor adjacent code unless needed for correctness.
- Do not touch or refactor or reformat unrelated code, unless explicitly part of the change or explicitly asked.
- Preserve backwards compatibility for user-facing APIs unless the app or API is unreleased or a breaking change is explicitly approved.
- Look at .github/workflows/ci_cd.yml and Makefile for the test flow.
- The flow requires several steps to reproduce and run locally and is not a direct pytest run.
- Add a regression test for bugs.
- For features, cover the main path plus a failure/edge case. Code coverage must be 90%.
- Look at existing tests for patterns, mainly in
tests/serverless/. - Tests should not be forced to increase coverage artificially; focus on meaningful coverage.
- Keep all test code in dedicated test files or folders, separate from production code.
- Use existing fixtures where possible.
- Run lint/checks, smoke tests, and focused tests locally after every commit and before finishing:
make check
make smoketest
uv run pytest path/to/test_file.py -q- Do not run full test suites by default. Run
make testonly when explicitly requested or after confirming it is needed for a broad or high-risk change.
- Commit often in small, sensible increments.
- Split large changes into separate commits by concern.
- Use detailed commit messages. Include a clear subject and a body that explains what changed, why it changed, and how it was verified.
- After every commit, run the focused quality gates listed above and follow the lockfile update workflow from the quick contract.
Keep imports grouped as:
- standard library
- third-party
- local package imports
Prefer raising repo-specific exceptions where appropriate (search for existing exception types rather than inventing new ones).
def function_name(param1, param2):
"""Brief summary.
Parameters
----------
param1 : type
Description.
param2 : type
Description.
Returns
-------
type
Description.
"""Build docs via:
make docsDocs sources live under doc/source/.
GitHub Actions jobs typically enforce:
- formatting / pre-commit
- unit tests
- smoke tests
- docs build (depending on workflow)
If you change:
pyproject.tomlor dependency groups → expect lockfile checks (uv lock --locked) to matter.- Check out README for instructions on setting up the development environment.
- Source:
src/ansys/dynamicreporting/core/adr_service.pyand related modules. - Backed by REST API calls to Ansys Dynamic Reporting service.
- Source:
src/ansys/dynamicreporting/core/utils/ - Common helpers for file handling, data conversion, REST interactions, etc.
- Source:
src/ansys/dynamicreporting/core/serverless/ - Backed by Django models + database (often PostgreSQL via psycopg)
- Source:
src/ansys/dynamicreporting/core/docker_support.py - Convenience script:
scripts/pull_adr_image.sh
- Helpers live in
codegen/ - Some core modules may be generated during build hooks; avoid editing outputs directly unless unavoidable.
- The repo uses tag-driven versioning through Hatch (
uv run hatch version). - See
scripts/tag_release.shandmake tag. - Releases are automated via GitHub Actions workflows.
- Never make releases by hand.
- Never do anything release-related, unless explicitly told to.
- Issues: https://github.com/ansys/pydynamicreporting/issues
- Discussions: https://discuss.ansys.com/
- Email: pyansys.core@ansys.com
Last updated: January 23, 2026 Maintained by: ANSYS, Inc. and Ansys ADR Team