Skip to content

Latest commit

 

History

History
323 lines (244 loc) · 13 KB

File metadata and controls

323 lines (244 loc) · 13 KB

AI Agents Guide for PyDynamicReporting

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.

Quick agent contract (what “done” means)

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 test only 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-extras and uv lock --upgrade, and commit any resulting uv.lock update so CI Security Scan checks do not fail.
  • Avoid unrelated reformatting and keep diffs tight.

Project overview

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 structure (high level)

├── 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, and build_info.py) may be generated via build hooks / codegen. Avoid hand-editing those unless you’re intentionally changing generation inputs.

Development setup (repo-native)

This repo uses uv + a checked-in lockfile (uv.lock). The Makefile wraps the canonical workflows.

Prerequisites

  • Python 3.10, 3.11, 3.12, or 3.13
  • uv
  • make (on Windows, make install uses Git Bash under the hood)

Install (preferred)

make install

What it does:

  • uv sync --frozen --all-extras (reproducible env from uv.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 .

Code style and standards

Formatting & imports

  • Black with line length 100 (see [tool.black] in pyproject.toml)
  • isort with Black profile and line length 100
  • CI style checks are enforced via pre-commit

Run the repo’s style gate:

make check

Docstrings

Use NumPy-style docstrings for public APIs and non-trivial internals.

Avoiding “generated-file drift” (important)

If you touch a file that is generated by codegen/ or the build hook, prefer:

  1. finding the source-of-truth input in codegen/,
  2. updating that input,
  3. regenerating/bumping in the standard workflow.

Development guardrails

Comments and maintainability

  • 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.

Architecture and reuse

  • 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.

Performance

  • 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.

Dependencies and library usage

  • 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.

Reliability

  • 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.

Types

  • 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.

Decision points

  • 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.

Testing

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 test

Tips 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.py and tests/serverless/conftest.py.
  • Keep test data in tests/test_data/ (or tests/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.

Branch conventions

Direct commits to main aren’t allowed.

Recommended prefixes (matches CONTRIBUTING.md):

  • fix/* – bug fixes and small patches
  • feat/* – new features
  • doc/* – documentation-only changes
  • maint/* – maintenance/CI
  • testing/* – test changes
  • junk/* – experimental work
  • no-ci/* – low-impact work that shouldn’t trigger CI
  • release/* – release-related work

Key dependencies (source of truth)

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

Making changes (workflow)

1) Triage & understand

  • 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.

2) Implement minimally

  • 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.

3) Add tests

  • 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.

4) Run focused quality gates (expected before finishing)

  • 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 test only when explicitly requested or after confirming it is needed for a broad or high-risk change.

5) Commit incrementally

  • 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.

Common code patterns

Imports

Keep imports grouped as:

  1. standard library
  2. third-party
  3. local package imports

Error handling

Prefer raising repo-specific exceptions where appropriate (search for existing exception types rather than inventing new ones).

Docstring template (NumPy)

def function_name(param1, param2):
    """Brief summary.

    Parameters
    ----------
    param1 : type
        Description.
    param2 : type
        Description.

    Returns
    -------
    type
        Description.
    """

Docs

Build docs via:

make docs

Docs sources live under doc/source/.

CI/CD notes (what agents should assume)

GitHub Actions jobs typically enforce:

  • formatting / pre-commit
  • unit tests
  • smoke tests
  • docs build (depending on workflow)

If you change:

  • pyproject.toml or dependency groups → expect lockfile checks (uv lock --locked) to matter.
  • Check out README for instructions on setting up the development environment.

Repo-specific notes

Service mode

  • Source: src/ansys/dynamicreporting/core/adr_service.py and related modules.
  • Backed by REST API calls to Ansys Dynamic Reporting service.

Utilities

  • Source: src/ansys/dynamicreporting/core/utils/
  • Common helpers for file handling, data conversion, REST interactions, etc.

Serverless mode

  • Source: src/ansys/dynamicreporting/core/serverless/
  • Backed by Django models + database (often PostgreSQL via psycopg)

Docker support

  • Source: src/ansys/dynamicreporting/core/docker_support.py
  • Convenience script: scripts/pull_adr_image.sh

Code generation

  • Helpers live in codegen/
  • Some core modules may be generated during build hooks; avoid editing outputs directly unless unavoidable.

Release tooling (FYI)

  • The repo uses tag-driven versioning through Hatch (uv run hatch version).
  • See scripts/tag_release.sh and make tag.
  • Releases are automated via GitHub Actions workflows.
  • Never make releases by hand.
  • Never do anything release-related, unless explicitly told to.

Getting help


Last updated: January 23, 2026 Maintained by: ANSYS, Inc. and Ansys ADR Team