Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
57 changes: 32 additions & 25 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,22 @@ on:
pull_request:
branches: [ main, maint-0.x ]

permissions:
contents: read

jobs:
test-python-312-single-user:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7
with:
# Full history and tags so setuptools-scm derives the real version
# for the distribution built by `make test-dist`.
fetch-depth: 0

- name: Set up Python 3.12
uses: actions/setup-python@v4
uses: actions/setup-python@v7
with:
python-version: "3.12"

Expand All @@ -27,7 +34,7 @@ jobs:
run: make lint

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@v4

- name: Generate certificates
run: make certs
Expand All @@ -44,7 +51,7 @@ jobs:
run: NIPYAPI_PROFILE=single-user PYTHONPATH=${{ github.workspace }}:$PYTHONPATH pytest --cov=nipyapi --cov-report=xml --cov-report=term-missing

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
uses: codecov/codecov-action@v7
with:
files: ./coverage.xml
fail_ci_if_error: false
Expand All @@ -59,13 +66,13 @@ jobs:
run: make down

test-python-311-single-user:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7

- name: Set up Python 3.11
uses: actions/setup-python@v4
uses: actions/setup-python@v7
with:
python-version: "3.11"

Expand All @@ -75,7 +82,7 @@ jobs:
pip install -e .[dev]

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@v4

- name: Generate certificates
run: make certs
Expand All @@ -94,13 +101,13 @@ jobs:
run: make down

test-python-310-single-user:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7

- name: Set up Python 3.10
uses: actions/setup-python@v4
uses: actions/setup-python@v7
with:
python-version: "3.10"

Expand All @@ -110,7 +117,7 @@ jobs:
pip install -e .[dev]

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@v4

- name: Generate certificates
run: make certs
Expand All @@ -129,13 +136,13 @@ jobs:
run: make down

test-python-39-single-user:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7

- name: Set up Python 3.9
uses: actions/setup-python@v4
uses: actions/setup-python@v7
with:
python-version: "3.9"

Expand All @@ -145,7 +152,7 @@ jobs:
pip install -e .[dev]

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@v4

- name: Generate certificates
run: make certs
Expand All @@ -164,13 +171,13 @@ jobs:
run: make down

test-python-312-secure-ldap:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7

- name: Set up Python 3.12
uses: actions/setup-python@v4
uses: actions/setup-python@v7
with:
python-version: "3.12"

Expand All @@ -180,7 +187,7 @@ jobs:
pip install -e .[dev]

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@v4

- name: Generate certificates
run: make certs
Expand Down Expand Up @@ -219,14 +226,14 @@ jobs:
run: make down

test-python-312-secure-mtls:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
# Note: This test can be flakey in local CI environments

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7

- name: Set up Python 3.12
uses: actions/setup-python@v4
uses: actions/setup-python@v7
with:
python-version: "3.12"

Expand All @@ -236,7 +243,7 @@ jobs:
pip install -e .[dev]

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@v4

- name: Generate certificates
run: |
Expand Down
45 changes: 25 additions & 20 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
.PHONY: clean clean-pyc clean-build clean-act clean-docker test docs help
.PHONY: clean clean-all clean-temp clean-certs clean-generated clean-pyc clean-build clean-act clean-docker install dist wheel sdist check-dist test-dist test docs help
.DEFAULT_GOAL := help

# Default NiFi/Registry version for docker compose profiles
NIFI_VERSION ?= 2.10.0
NIFI_VERSION ?= 2.12.0

# Load .env file if it exists (for secrets like GH_REGISTRY_TOKEN)
# WARNING: All variables from .env are exported and can override profile settings.
Expand Down Expand Up @@ -95,35 +95,37 @@ help:
## Operational Targets ##
#################################################################################

clean: clean-build clean-pyc clean-temp ## remove all build, test, coverage and Python artifacts
clean: clean-build clean-pyc clean-temp ## remove build, coverage and Python artifacts (keeps test certificates)

clean-all: clean-build clean-pyc clean-temp openapi-clean ## nuclear clean: removes ALL artifacts including committed generated code
@echo "=== Nuclear Clean: Removing ALL Artifacts ==="
clean-all: clean-build clean-pyc clean-temp clean-certs openapi-clean clean-generated ## nuclear clean: removes ALL artifacts including committed generated code
@echo "ALL artifacts removed: build, Python, OpenAPI, committed code, test certificates."
@echo "Use 'make certs', 'make gen-clients' and 'make docs' to regenerate them."

clean-generated: ## remove committed generated code (API clients, structured docs); nipyapi cannot be imported until 'make gen-clients'
@echo "WARNING: This removes committed generated code (API clients, docs)!"
# Generated API clients (committed code)
rm -rf nipyapi/nifi/* nipyapi/registry/* || true
# Generated documentation (committed code)
rm -rf docs/nipyapi-docs || true
@echo "ALL artifacts removed: build, Python, OpenAPI, committed code, test certificates."
@echo "Use 'make openapi-generate' and 'make docs' to regenerate committed code."

clean-temp: ## remove temporary artifacts but preserve committed code
clean-temp: ## remove coverage, docs build and generation temp files; preserves committed code and test certificates
# Coverage artifacts
rm -rf htmlcov/ .coverage coverage.xml .pytest_cache || true
# Documentation build artifacts
rm -rf docs/_build/* || true
# Temporary generation files and cache
rm -rf resources/client_gen/_tmp/* resources/client_gen/_cache/* || true
# Test certificates and configuration (non-committed test artifacts)

clean-certs: ## remove generated test certificates and env files (regenerate with 'make certs')
rm -rf resources/certs/ca/ resources/certs/nifi/ resources/certs/registry/ resources/certs/client/ resources/certs/truststore/ || true
rm -f resources/certs/certs.env resources/certs/nifi.env resources/certs/registry.env || true
# Auto-generated version file
rm -f nipyapi/_version.py || true

clean-build: ## remove build artifacts
rm -fr build/
rm -fr dist/
rm -fr .eggs/
# Auto-generated version file (rewritten by setuptools-scm on build)
rm -f nipyapi/_version.py || true
find . -path ./.venv -prune -o -name '*.egg-info' -exec rm -fr {} +
find . -path ./.venv -prune -o -name '*.egg' -exec rm -rf {} +

Expand Down Expand Up @@ -157,7 +159,7 @@ clean-docker: clean-act ## comprehensive Docker cleanup: act + containers + volu
docker volume prune -f || true
@echo "Comprehensive Docker cleanup complete"

install: clean ## install the package to the active Python's site-packages
install: clean-build ## install the package to the active Python's site-packages
$(PIP) install .

dev-install: ## install dev extras for local development
Expand Down Expand Up @@ -313,19 +315,21 @@ test-specific: ## DEPRECATED: use 'make test PYTEST_ARGS="..."' instead


# Build & Documentation
dist: clean ## builds source and wheel package using modern build system
dist: clean-build ## builds source and wheel package using modern build system
$(PYTHON) -m build

wheel: clean ## builds wheel package only
wheel: clean-build ## builds wheel package only
$(PYTHON) -m build --wheel

sdist: clean ## builds source distribution only
sdist: clean-build ## builds source distribution only
$(PYTHON) -m build --sdist

check-dist: dist ## validate distribution files
check-dist: ## validate distribution files (builds dist only if dist/ is empty)
@ls dist/*.whl >/dev/null 2>&1 || $(MAKE) dist
$(PYTHON) -m twine check dist/*

test-dist: dist ## test that built distribution can be imported and used
test-dist: ## test that built distribution can be imported and used (builds dist only if dist/ is empty)
@ls dist/*.whl >/dev/null 2>&1 || $(MAKE) dist
$(PYTHON) resources/scripts/test_distribution.py

docs: ## generate Sphinx HTML documentation with improved navigation
Expand Down Expand Up @@ -367,17 +371,18 @@ sandbox: ensure-certs ## create isolated environment with sample objects: make s

rebuild-all: ## comprehensive rebuild: clean -> certs -> extract APIs -> gen clients -> test all -> build -> validate -> docs
@echo "Starting comprehensive rebuild from clean slate..."
@echo "=== 1/9: Clean All Artifacts ==="
$(MAKE) clean-all
@echo "=== 1/9: Clean All Artifacts (generated code is removed at step 5) ==="
$(MAKE) clean-build clean-pyc clean-temp clean-certs openapi-clean
@echo "=== 2/9: Generate Certificates ==="
$(MAKE) certs
@echo "=== 3/9: Extract OpenAPI Specs ==="
$(MAKE) up NIPYAPI_PROFILE=single-user
$(MAKE) wait-ready NIPYAPI_PROFILE=single-user
$(MAKE) fetch-openapi
$(MAKE) fetch-openapi-base
@echo "=== 4/9: Augment OpenAPI Specs ==="
$(MAKE) augment-openapi
@echo "=== 5/9: Generate Fresh Clients ==="
$(MAKE) clean-generated
$(MAKE) gen-clients
@echo "=== 6/9: Test All Profiles with Fresh Clients ==="
$(MAKE) test-all
Expand Down
5 changes: 3 additions & 2 deletions docs/contributing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -332,8 +332,9 @@ NiPyAPI uses Makefile targets as the primary automation interface. Run ``make he

make dev-install # Install with dev dependencies (uses uv if available, pip otherwise)
make docs-install # Install documentation dependencies
make clean # Remove build, pyc, and temp artifacts
make clean-all # Nuclear clean: removes ALL including generated code
make clean # Remove build, pyc, coverage and temp artifacts (keeps test certificates)
make clean-certs # Remove generated test certificates (regenerate with make certs)
make clean-all # Nuclear clean: removes ALL including certificates and generated code

**Testing Workflow**
::
Expand Down
51 changes: 51 additions & 0 deletions docs/history.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,57 @@
History
=======

1.8.0 (2026-10-22)
-------------------

| NiFi 2.12.0 support, parameter provider helpers and behaviour fixes

**Behaviour Changes**

This is a minor release: no public function was removed or had its signature changed, but the following existing functions now behave differently. Review callers of ``get_process_group`` in particular.

- **get_process_group** (high-traffic): a lookup by an ID that does not exist now returns ``None`` instead of raising ``ValueError("Unable to locate group ...")``. Code that caught ``ValueError`` to detect a missing group should check for ``None`` instead. Other API errors still raise ``ValueError``, and lookups by name are unchanged. The ``nipyapi.ci`` commands report a missing group as ``Process group not found: <id>``. See Bug Fixes.
- **Parameter context updates**: ``update_parameter_context``, and the helpers that call it (``rename_parameter_context``, ``upsert_parameter_to_context``, ``delete_parameter_from_context`` and ``update_parameter_in_context``), now raise ``ValueError`` when the update request completes with a ``failureReason``. Previously the failure was ignored and the re-read context was returned as if the update had succeeded.
- **verify_controller and verify_processor**: a verification request that completes with a ``failureReason`` now raises ``ValueError``. A timeout or interruption no longer sends a DELETE that would cancel the server-side request, and an error deleting a completed request now propagates instead of being logged and ignored. Individual ``FAILED`` verification results are still returned as data.
- **ensure_management_controller**: now matches controller-level services only, and raises ``ValueError`` if several share the requested name. Previously a process-group service with the same name could be found and reconfigured. See Bug Fixes.
- **ParameterGroupConfigurationEntity**: ``parameter_sensitivities`` now validates its values rather than its keys and accepts ``None``, so parameter provider responses deserialize. See Bug Fixes.

Wait timings, return types of existing functions and behaviour against supported NiFi 2.x servers are otherwise unchanged.

**Deprecations**

- **Python 3.9**: support is deprecated and will be removed in an upcoming release. Python 3.9 reached end of life in October 2025, and ``actions/setup-python`` publishes no Python 3.9 build for the Ubuntu 26.04 runner image, so CI is pinned to ``ubuntu-24.04`` for this release. 1.8.0 is still tested on Python 3.9; plan to move to Python 3.10 or later.

**Supported Versions**

- Bumped the supported and tested NiFi/Registry version from 2.10.0 to 2.12.0 and regenerated the NiFi and Registry API clients against the 2.12.0 OpenAPI specification. The change to the generated surface is additive: no API methods or models were removed or renamed. New operations include connector migration and backlog requests, processor backlog requests, and versioned flow rebase.
- The seeded test flows in the companion ``nipyapi-actions`` repository were updated to NiFi 2.12.0 component bundles. A flow saved on an older NiFi version reports an environmental "Component Bundle Changed" local modification when deployed to a newer one.

**Bug Fixes**

- **get_process_group**: a lookup by an ID that does not exist raised ``ValueError`` ("Unable to locate group ...") instead of returning ``None`` as its 404 handler intends, unlike ``get_processor`` and ``get_parameter_context``. It now returns ``None``; other API errors still raise ``ValueError``. The ``nipyapi.ci`` commands already handled ``None``, so their missing-group error is now ``Process group not found: <id>``.
- **ensure_management_controller**: the lookup by name also matched process-group services, so an existing process-group service with the same name could be reconfigured and enabled instead of a controller-level one being created. It now matches controller-level services only, and raises ``ValueError`` if several share the name.
- **Parameter provider models**: ``ParameterGroupConfigurationEntity.parameter_sensitivities`` validated its map keys (parameter names) against the ``SENSITIVE``/``NON_SENSITIVE`` enum instead of its values, so parameter provider fetch and apply responses could not be deserialized. Values are now validated, and ``None`` (staged on the first fetch of a new group) is accepted.

**Parameter Providers and Contexts**

- Added provider discovery, type lookup, property updates, fetch, apply, and combined fetch/apply helpers to ``nipyapi.parameters``. Apply retains staged sensitivity and ``synchronized`` choices unless overridden, and defaults unset choices to sensitive and synchronized, matching NiFi. Unknown parameter names in ``sensitivities`` raise ``ValueError``, and an apply with no synchronized groups logs a warning. The combined helper accepts the same override arguments.
- Added ordered context inheritance updates, process-group bound-context lookup, and local sensitive aliases to parameters in provider-created contexts. Connecting keeps an already inherited source in place unless a higher-precedence context shadows a mapped name, rejects non-sensitive source parameters, and keeps descriptions of overwritten aliases. New asynchronous helpers return the completed request DTO, including affected components. Existing context-update return types are unchanged.
- Standardized provider apply, context update and processor/controller verification on ``utils.wait_for_request``: completed requests are deleted, including failed ones, and an unfinished request is never cancelled implicitly. If a request fails and its cleanup also fails, the request failure is raised. See Behaviour Changes.
- Added ``canvas.list_all_management_controllers()`` and ``canvas.get_management_controller()`` for controller-level services without process-group-scoped results.

**Maintenance**

- Corrected the ``canvas.get_controller()`` docstring: ``bool_response=True`` returns ``False`` only when the API call fails (for example a missing ID); a name with no match returns ``None``. Behaviour is unchanged.
- Build targets no longer delete test certificates or coverage reports: ``make dist``, ``wheel``, ``sdist`` and ``install`` now clean only build output, and ``make check-dist`` and ``make test-dist`` reuse an existing build rather than rebuilding it. Certificates are removed only by the new ``make clean-certs`` or by ``make clean-all``.
- CI: the job that runs ``make test-dist`` now checks out full history and tags, so the test wheel carries the real version instead of the ``0.0.1.dev1+unknown`` that setuptools-scm falls back to in a shallow clone. ``make test-dist`` now fails on such a fallback version. The workflow actions move to their current Node 24 releases (checkout v7, setup-python v7, codecov v7, setup-buildx v4), and jobs are pinned to ``ubuntu-24.04``, because setup-python publishes no Python 3.9 build for the Ubuntu 26.04 image that ``ubuntu-latest`` is moving to. The workflow now limits its ``GITHUB_TOKEN`` to read-only repository contents.

- Removed version guards and branches for NiFi releases older than 2.0, which nipyapi 1.x does not support. Parameter functions no longer make an extra ``/flow/about`` request on each call. ``canvas.list_all_processors``, ``canvas.list_all_controllers`` and ``nifi_registry.save_flow_ver`` now always use the 2.x API path they already took on supported servers.

**Generated Clients**

- **Configuration.client_side_validation**: New flag (default ``True``) on the NiFi and Registry ``Configuration`` objects. Setting it to ``False`` disables enum validation in generated models, for use against servers that return values the generated enums do not list yet.

1.7.0 (2026-07-18)
-------------------

Expand Down
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Contents:
profiles
security
extensions
parameters
migration
nipyapi-docs/api_reference
contributing
Expand Down
1 change: 1 addition & 0 deletions docs/nipyapi-docs/core_modules.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ They wrap the lower-level generated API clients with Pythonic interfaces.
core_modules/ci
core_modules/canvas
core_modules/versioning
core_modules/nifi_registry
core_modules/security
core_modules/parameters
core_modules/profiles
Expand Down
9 changes: 9 additions & 0 deletions docs/nipyapi-docs/core_modules/nifi_registry.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Nifi_Registry
=============

Nifi_Registry functionality

.. automodule:: nipyapi.nifi_registry
:members:
:undoc-members:
:show-inheritance:
4 changes: 4 additions & 0 deletions docs/nipyapi-docs/nifi_apis/connectors_api.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.. automodule:: nipyapi.nifi.apis.connectors_api
:members:
:undoc-members:
:show-inheritance:
Loading
Loading