Skip to content

Conversation

@Chaffelson
Copy link
Owner

@Chaffelson Chaffelson commented Dec 10, 2025

feat: Add CLI with CI operations for NiFi automation

Description

This PR adds a command-line interface to nipyapi, enabling shell scripting, CI/CD pipelines, and interactive exploration of NiFi deployments.

Motivation

nipyapi has always provided excellent Python API coverage for Apache NiFi, but many automation scenarios require shell-based tooling:

  • CI/CD pipelines (GitHub Actions, GitLab CI) that orchestrate flow deployments
  • DevOps workflows that integrate NiFi with other shell-based tools
  • Quick interactive exploration without writing Python scripts

This CLI bridges that gap while maintaining nipyapi's design philosophy of sensible defaults and clear interfaces.

Features

Command-Line Interface (nipyapi[cli])

  • Built on Google Fire for automatic command discovery and help generation
  • Exposes all nipyapi high-level modules: canvas, versioning, nifi_registry, parameters, security, system, profiles, bulletins, extensions
  • JSON output by default, with automatic CI platform detection (GitHub Actions, GitLab CI)
  • Structured error responses with captured logs for debugging
  • Profile-based configuration via ~/.nipyapi/profiles.yml or environment variables

CI Operations Module (nipyapi.ci)

  • 22 high-level operations designed for automation:
    • ensure_registry - Create/update Git Flow Registry Client (GitHub/GitLab)
    • deploy_flow - Deploy versioned flow from registry to canvas
    • start_flow / stop_flow - Manage flow execution with controller service handling
    • get_status - Comprehensive status including bulletins and invalid processors
    • list_flows - List process groups with version control state
    • get_flow_versions - List version history for a versioned flow
    • change_flow_version - Switch to specific version or latest
    • commit_flow - Save flow to version control (initial or subsequent)
    • detach_flow - Remove version control (for forking workflows)
    • get_flow_diff - Get local modifications to a versioned flow
    • revert_flow - Discard uncommitted local changes
    • configure_params / configure_inherited_params - Set parameter values with inheritance support
    • upload_asset - Upload files to parameter contexts
    • cleanup - Stop and delete process groups
    • purge_flowfiles - Clear queued data from connections
    • resolve_git_ref - Resolve branch/tag to commit SHA
    • export_flow_definition - Export process group as JSON/YAML (no registry required)
    • import_flow_definition - Import flow definition file as new process group
    • list_nars / upload_nar / delete_nar - Manage custom NAR extensions

Canvas Module Enhancements (nipyapi.canvas)

  • FlowFile inspection: list_flowfiles, get_flowfile_details, get_flowfile_content, peek_flowfiles
  • Component state management: get_processor_state, clear_processor_state, get_controller_state, clear_controller_state
  • Enhanced schedule_processor: now supports RUN_ONCE and DISABLED states in addition to RUNNING/STOPPED
  • Documentation helpers: get_processor_docs, get_controller_service_docs for programmatic processor discovery

Bulletins Module (nipyapi.bulletins)

  • get_bulletin_board with filtering by source name and message pattern
  • clear_all_bulletins for NiFi 2.7.0+ (clear bulletins between test runs)

Layout Module (nipyapi.layout)

  • Canvas organization utilities: align_pg_grid, align_processors_horizontal, stack_process_groups
  • Smart positioning: below(), fork(), right_of(), left_of() for flow building
  • Consistent spacing and alignment for readable flow designs

Extensions Module (nipyapi.extensions)

  • NAR (NiFi Archive) management for custom processors and controller services
  • Python processor lifecycle handling with initialization state tracking
  • Multi-version bundle management for processor upgrades
  • Key functions:
    • list_nars / get_nar / get_nar_details - Query installed extensions
    • upload_nar - Upload with automatic installation wait and processor discovery
    • delete_nar - Safe deletion with cleanup verification and init-state guards
    • get_processor_init_status / wait_for_processor_init - Python processor lifecycle
    • get_processor_bundle_versions / change_processor_bundle_version - Multi-version support

NiFi Registry Module (nipyapi.nifi_registry)

  • Extracted from versioning.py for clearer module organization
  • Contains NiFi Registry-specific operations: bucket management, flow versions, deploy/save
  • versioning.py retains Git registry functions and provides backwards-compatible aliases
  • Key functions: list_registry_buckets, create_registry_bucket, save_flow_ver, deploy_flow_version, etc.

Utilities Enhancements (nipyapi.utils)

  • fs_write now supports binary=True for raw byte content (e.g., FlowFile downloads)
  • is_uuid helper for detecting UUID strings (format validation only, not RFC 4122)
  • format_timestamp for NiFi-compatible timestamp formatting

Enhanced Profile System

  • --profile option for explicit profile selection
  • Environment variable auto-detection for CI platforms
  • Support for bearer token, OIDC, mTLS, LDAP, and basic auth

Example Usage

# Quick connectivity test
nipyapi system get_nifi_version_info

# Deploy a flow from Git registry
nipyapi ci ensure_registry --repo myorg/nifi-flows --token $GH_TOKEN
nipyapi ci deploy_flow --bucket connectors --flow postgresql

# Start and monitor
nipyapi ci start_flow --process_group_id $PG_ID
nipyapi ci get_status --process_group_id $PG_ID

# Version control operations
nipyapi ci list_flows                              # List flows with version state
nipyapi ci get_flow_diff --process_group_id $PG_ID # Get local modifications
nipyapi ci commit_flow --process_group_id $PG_ID   # Save changes to registry

# Parse output with jq
REGISTRY_ID=$(nipyapi versioning list_registry_clients | jq -r '.registries[0].component.id')

CI Platform Integration

The CLI auto-detects CI environments and formats output appropriately:

  • GitHub Actions: key=value format with heredoc syntax for multiline values
  • GitLab CI: KEY=VALUE dotenv format with proper quoting for special characters
  • Values containing shell metacharacters (|, [, ], spaces) are automatically quoted
# GitHub Actions
- run: nipyapi ci deploy_flow --bucket flows --flow myflow >> $GITHUB_OUTPUT
- run: nipyapi ci start_flow --process_group_id ${{ steps.deploy.outputs.process-group-id }}

# GitLab CI
script:
  - nipyapi ci deploy_flow --bucket flows --flow myflow > deploy.env
artifacts:
  reports:
    dotenv: deploy.env

Documentation

  • docs/cli.rst - Complete CLI reference with all modules and options
  • docs/ci.rst - CI operations guide with parameter tables and examples
  • docs/profiles.rst - Enhanced profile configuration documentation
  • docs/extensions.rst - NAR management and Python processor lifecycle guide

Testing

  • 50+ files changed, ~12,000 lines added
  • New test modules: test_cli.py, test_ci.py, test_layout.py, test_profiles.py, test_extensions.py
  • Programmatic NAR generation for extension testing (create_test_nar() fixture)
  • Tests run against Docker infrastructure with multiple auth profiles

Installation

# Standard installation
pip install "nipyapi[cli]"

# From this branch
pip install "nipyapi[cli] @ git+https://github.com/Chaffelson/nipyapi.git@feature/cli"

Breaking Changes

None. The CLI is an optional install (nipyapi[cli]) and all existing Python APIs remain unchanged.

@codecov
Copy link

codecov bot commented Dec 10, 2025

Codecov Report

❌ Patch coverage is 79.14384% with 609 lines in your changes missing coverage. Please review.
✅ Project coverage is 75.87%. Comparing base (b69632a) to head (a1d2fd3).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
nipyapi/layout.py 82.87% 74 Missing ⚠️
nipyapi/canvas.py 86.91% 50 Missing ⚠️
nipyapi/cli.py 77.93% 47 Missing ⚠️
nipyapi/nifi_registry.py 75.72% 42 Missing ⚠️
nipyapi/ci/get_status.py 59.18% 40 Missing ⚠️
nipyapi/extensions.py 84.73% 40 Missing ⚠️
nipyapi/bulletins.py 60.21% 37 Missing ⚠️
nipyapi/versioning.py 66.66% 27 Missing ⚠️
nipyapi/ci/cleanup.py 69.76% 26 Missing ⚠️
nipyapi/ci/list_registry_flows.py 33.33% 26 Missing ⚠️
... and 24 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #394      +/-   ##
==========================================
+ Coverage   70.84%   75.87%   +5.02%     
==========================================
  Files           9       41      +32     
  Lines        2024     4738    +2714     
==========================================
+ Hits         1434     3595    +2161     
- Misses        590     1143     +553     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Chaffelson Chaffelson force-pushed the feature/cli branch 4 times, most recently from 712afd5 to dbabc28 Compare December 12, 2025 15:09
@ottobackwards
Copy link
Collaborator

I really like how this is shaping up, let me know when you are out of draft

- Add nipyapi CLI with 'ci' subcommand for NiFi CI/CD operations
- Profile auto-resolution: switch() without args auto-detects env vars or profile file
- CI functions: deploy_flow, start_flow, stop_flow, get_status, cleanup, configure_params
- New functions: configure_inherited_params, purge_flowfiles, upload_asset
- get_status defaults to root process group when no PG specified
- Log control via NIFI_LOG_LEVEL and NIFI_LOG_ON_ERROR env vars
- Suppress SSL warnings to keep CI output clean
- Convert snake_case to kebab-case for GitHub Actions output format
- resolve_git_ref to resolve tags/branches to SHAs
…cture

Layout Module:
- New nipyapi/layout.py with intelligent canvas positioning
- Process group grid alignment (align_pg_grid, suggest_pg_position)
- Flow layout functions (below, above, right_of, left_of, fork, new_flow)
- Component movement with self-loop bend handling
- Flow transposition and de-overlap capabilities
- Spine/branch detection for flow restructuring (find_flow_spine, get_side_branches)
- Automated flow layout (suggest_flow_layout)

Canvas Enhancements:
- get_flow_components() for graph traversal of connected components
- Automatic bend calculation for self-loop connections
- Bends parameter support in create_connection()

CLI Improvements:
- Expose layout functions via CLI (align_pg_grid, suggest_pg_position, etc.)
- SafeModule wrapper for structured error handling
- Custom serializer for formatted output

Client Generation:
- Add octet-stream handler to rest.mustache template
- Regenerate NiFi and Registry clients with binary upload support

Profile System:
- Fix get_default_profile_name() to honor NIPYAPI_PROFILES_FILE env var
- Improve profile resolution order for testing isolation

CI Module:
- Fix purge_flowfiles.py to use detail='all' for process group status

Test Infrastructure:
- Add NIPYAPI_PROFILES_FILE to Makefile for test isolation
- Update conftest.py to use env var for profiles path
- Add comprehensive tests for layout, CLI, CI, canvas, and parameters
- 332 tests passing, lint clean (10.00/10)
- CI functions no longer call profiles.switch() internally
- Profile configuration is now solely the responsibility of the caller
- CLI main() handles switch() with --profile arg or auto-resolution
- Fixes bug where --profile flag was ignored by CI commands

Also includes:
- Add --profile CLI option for explicit profile selection
- Add NIPYAPI_PROFILE env var support in switch() auto-resolution
- Update profiles.rst documentation
- Add tests for new profile resolution behavior
- Regenerate NiFi and Registry clients from augmented OpenAPI specs
- Restore basicAuth in Registry configuration.py and access_api.py
- Fix mock patch path in test_ci.py for Python 3.9 compatibility
  (use @patch('requests.get') instead of module path)
The ensure_registry function was resolving the token before determining
the provider, always preferring GH_REGISTRY_TOKEN regardless of whether
gitlab was specified. This caused GitLab deployments to fail when both
tokens were set.

Now resolves provider first, then selects the appropriate token:
- gitlab: GL_REGISTRY_TOKEN first, fallback to GH_REGISTRY_TOKEN
- github: GH_REGISTRY_TOKEN first, fallback to GL_REGISTRY_TOKEN
Replace string 'in' check with urlparse().hostname for cleaner URL validation.
CLI coverage: 62% -> 81%
- Add tests for list serialization, heredoc format, _to_dict methods
- Add tests for _parse_profile_arg function
- Add tests for SafeModule error handling and log level inclusion

Profiles coverage: 68% -> 74%
- Add tests for unicode error handling in properties files
- Add tests for get_default_profile_name edge cases

CI coverage: 50% -> 58%
- ensure_registry: 17% -> 95% (validation + token priority tests)
- deploy_flow: 17% -> 61% (validation tests)
- configure_params: 27% -> 49% (JSON validation tests)

Overall coverage: 66% -> 69%
CLI documentation (cli.rst):
- Installation options (pip, uv, uvx)
- Configuration (env vars, profiles, priority)
- Discovering commands with --help
- All available modules with API reference links
- Output formatting (JSON, GitHub Actions, GitLab)
- Note that low-level nifi/registry APIs not exposed

CI documentation (ci.rst):
- All 14 CI operations with full parameter tables
- configure_inherited_params for inheritance-aware updates
- resolve_git_ref utility function
- Environment variable reference
- Complete workflow examples (shell, GitHub, GitLab, Python)

Other changes:
- Fix test_safe_module_error_handling for CI environments
- Fix security.rst title (was incorrectly 'NiPyAPI 2')
- Add layout module to core_modules docs
- Update dependencies list
…t isolation

Add integration tests against real NiFi for better coverage:

test_ci.py:
- configure_inherited_params: 10 tests (validation + integration)
- upload_asset: 8 tests (file path, PG resolution, param linking)

test_parameters.py:
- get_parameter_context_hierarchy: 3 tests
- get_parameter_ownership_map: 2 tests
- update_parameter_in_context: 4 tests

test_layout.py:
- move_port: 3 tests (input, output, no-refresh)
- move_component with port: 1 test
- snap_position, get_pg_grid_position, left_of, check_overlap: 5 tests

test_versioning.py:
- Fix test isolation: wait for async revert to complete in
  test_revert_flow_ver_wait_false before test ends, preventing
  revision conflicts in subsequent tests using same fixture
New CI functions:
- commit_flow: save flow to version control (initial or subsequent)
- get_flow_versions: list version history for a flow
- detach_flow: remove version control (for forking workflows)
- get_flow_diff: get local modifications to a versioned flow

Renames for consistency:
- change_version -> change_flow_version
- get_versions -> list_flows

New versioning helper:
- get_local_modifications: helper for fetching local changes

Improvements:
- list_flows: use nipyapi.utils.getenv_bool for env var parsing
- list_flows: use nipyapi.canvas.get_flow helper instead of direct API
- save_git_flow_ver: accept string process group ID

Tests:
- Added comprehensive tests for all new CI functions
- Fixed flaky versioning tests with proper state handling
- Improved test isolation in shared fixtures
- Add export_flow_definition CI function for exporting process groups to files
- Add import_flow_definition CI function for importing flow definitions from files
- Support JSON and YAML formats for export
- Add include_referenced_services option to include external controller services
- Use smart positioning (suggest_pg_position) when import location not provided
- Add 10 tests covering validation, roundtrip export/import, and file operations
- Add nipyapi.extensions module for NAR upload, delete, download
- Add Python processor initialization status and wait functions
- Add processor bundle version management for multi-version NARs
- Implement defensive delete_nar with initialization guard and cleanup wait
- Implement two-phase upload_nar wait (install + processor discovery)
- Fix canvas.create_processor to include bundle for multi-version support
- Add programmatic NAR generation for testing (create_test_nar)
- Add comprehensive tests for extension operations
- Add extensions operations guide (docs/extensions.rst) covering NAR lifecycle,
  Python processor initialization, version management, and troubleshooting
Values with spaces, pipes, brackets, and other shell special characters
are now properly quoted in dotenv output format. This prevents export
failures when values contain characters like | [ ] that break shell parsing.

Embedded double quotes are escaped with backslash.
…gs and optional parameters

- Add include_bindings parameter to include bound_process_groups for each context
- Add include_parameters parameter to optionally exclude parameter details
- Add description field to parameter output for better context
- Add tests for new functionality including transitive binding behavior
- Useful for cleanup workflows and parameter inspection during deployment
- Add --version/-V flags to display version and exit
- Add -v/-vv/-vvv flags to control log verbosity
- Refactor _parse_profile_arg to _parse_cli_flags for combined parsing
- Add _apply_verbosity to set NIFI_LOG_LEVEL from verbosity count
- Add comprehensive unit tests for flag parsing
- Add integration tests for version output
- Accept either a string ID or ProcessGroupEntity for parent_pg parameter
- Maintains backward compatibility with existing code using entities
- Raises TypeError with clear message for invalid types
- Supports 'root' as parent_pg for creating PGs on root canvas
- Add tests for string ID, UUID string, and invalid type cases
… handling

Registry client improvements:
- versioning.get_registry_client: add greedy parameter (default True for compat)
- ci.deploy_flow: accept registry client name or ID, add greedy param
- ci.list_registry_flows: new function to list flows in registry bucket

Canvas improvements:
- create_process_group: accept string ID or ProcessGroupEntity for parent_pg
- delete_remote_process_group: add force param to stop transmission before delete
- set_remote_process_group_transmission: wait for state change before returning

Test fixes:
- conftest: use force=True when cleaning up RPGs
- Add tests for greedy parameter and list_registry_flows validation
Previously, lists nested within dict results were converted via str()
which produces Python repr format with single quotes. This is not valid
JSON and breaks downstream parsing.

Now lists and dicts at leaf positions are JSON-serialized with json.dumps()
producing valid JSON with double quotes.

Fixes output for: list_flows, list_registry_flows, get_flow_versions,
get_flow_diff, and any future CI functions returning list values.

Added tests for nested list serialization in both GitHub and dotenv formats.
… name

- Add is_uuid() function to nipyapi/utils.py for UUID format detection
- Update deploy_flow and list_registry_flows to auto-detect if registry_client is UUID (ID) or name
- Add comprehensive tests for is_uuid() in test_utils.py
- Update docstrings to document auto-detection behavior
- Add get_connection() to fetch connection by ID or entity
- Add update_connection() with name/bends parameters (bends=[] clears)
- Add clear_flow_bends() to clear bends before flow reorganization
- Update get_flow_components() to return FlowSubgraph(components, connections)
- Add include_retry parameter to move_component/move_processor
- Refactor transpose_flow to handle all bends in single pass
- Add comprehensive tests for new functionality
- Add nipyapi.canvas.verify_controller() for controller service verification
- Add nipyapi.canvas.verify_processor() for processor verification
- Add nipyapi.ci.verify_config() for batch verification of process groups
- Add refresh parameter to delete_controller and update_controller
- Improve delete_controller to accept ID or object
- Add PYTEST_ARGS support to Makefile test target
- Add fix_multi_version_nars module-scoped fixture for test optimization
- Remove useless @pytest.mark.usefixtures() decorator
- Extension tests now ~27% faster with shared NAR fixtures
- Add list_orphaned_contexts() to parameters module for detecting
  parameter contexts not bound to any process groups
- Enhance get_bulletin_board() with pg_id, source_name, message,
  and limit filters for scoped bulletin retrieval
- Add delete_orphaned_contexts option to ci.cleanup() for safe
  removal of unused parameter contexts after PG deletion
- Add comprehensive tests for all new functionality

Note: NiFi does not provide an API to clear bulletins in 2.6.0.
Clear bulletins API was introduced in 2.7.0 - upgrade planned separately.
…ring

New nipyapi.bulletins module:
- get_bulletins(): controller-level bulletins
- get_bulletin_board(): filtered bulletins returning BulletinDTO directly
- clear_*_bulletins(): component-specific clearing (10 functions)
- clear_all_bulletins(): high-level helper for CI

Additional changes:
- nipyapi.profiles: add list_profiles, show, current commands
- nipyapi.utils: add format_timestamp utility
- nipyapi.ci.get_status: fix to capture controller service bulletins
- nipyapi.canvas: bulletin functions now alias to bulletins module
- Makefile: intelligent uv/pip detection
- docs: updated contributing guide, module documentation
- Add get_processor_state and clear_processor_state for processor state inspection
- Add get_controller_state and clear_controller_state for controller service state
- All functions accept entity objects or ID strings
- Fix CLI --help flag handling in SafeModule wrapper
- Remove unused LogCapture.all_records attribute
- Add fix_state_flow test fixture with MapCacheServer and ListFile
- Add comprehensive tests for state operations
- Add export_parameters CI command for exporting parameter values
- Add --parameters_file option to configure_inherited_params for file-based import
- Add parameter_context_handling option to deploy_git_registry_flow for VCS
- Add deploy_flow CI command parameter_context_handling support
- Fix test fixture isolation to prevent shared fixtures being deleted
- Fix parameter context cleanup version check logic
- Add ACTIVE_PROFILES_PATH for consistent profile file handling
- Add parameter inheritance tests for VCS deployments
Add 43 new tests for CLI handling of complex JSON objects:

- 19 JSON input parsing tests (quotes, newlines, backslashes, nested
  structures, Unicode, null/empty values, mixed types)
- 4 roundtrip tests (serialize -> parse verification)
- 8 CLI subprocess tests (verify JSON passes through CLI correctly)
- 12 CI function tests for configure_params complex inputs

These tests verify AI agents can use the nipyapi CLI directly for
common operations without needing to write Python code for complex
parameter structures.
In GitHub Actions CI, GITHUB_ACTIONS=true causes the CLI to
auto-detect 'github' output format (key=value), but the tests
expect JSON output for parsing. Force NIFI_OUTPUT_FORMAT=json
in the subprocess environment to ensure consistent JSON output.

Fixes JSONDecodeError in configure_params CLI tests.
- Create AGENTS.md for AI agent guidance (consuming/contributing sections)
- Update contributing.rst with docstring standards and discovery patterns
- Fix all 51 Sphinx docstring warnings (nested lists, Example formatting)
- Standardize Example:: format across 91 instances with required blank lines
- Fix RST title underlines in ci.rst, security.rst
- Add cross-reference notation guidance for Sphinx
- Add module intent comments to __init__.py
New features:
- get_processor_docs(processor): retrieve full processor documentation including
  property_descriptors, tags, use cases. Accepts ProcessorEntity, DocumentedTypeDTO,
  or processor type name string.

- schedule_processor() enhancements:
  - Now accepts processor ID string or ProcessorEntity object
  - Supports all processor states: RUNNING, STOPPED, DISABLED, RUN_ONCE
  - Uses direct processor API for reliable state transitions
  - Backwards compatible: bool values still work (True=RUNNING, False=STOPPED)

Client fixes:
- Add nifi_processor_state_enum.py augmentation to fix upstream NiFi OpenAPI bug
  where ProcessorDTO.state enum was missing transitional states

Testing improvements:
- Add pytest filterwarnings config to suppress InsecureRequestWarning in tests
- Add comprehensive tests for new functionality

Docs:
- Minor AGENTS.md improvement: venv activation reminder
- nipyapi.canvas: Add list_flowfiles, get_flowfile_details, get_flowfile_content, peek_flowfiles
- get_flowfile_content supports decode options (auto/text/bytes) and output_file saving
- nipyapi.utils.fs_write: Add binary=False parameter for raw byte writing (backwards compatible)
- Tests: Add test_fs_write_binary, expand test_get_flowfile_content coverage
@Chaffelson Chaffelson requested a review from Copilot December 30, 2025 07:51
@Chaffelson Chaffelson self-assigned this Dec 30, 2025
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a comprehensive CLI interface to nipyapi, enabling shell-based automation and CI/CD integration while preserving backward compatibility. The implementation includes 22 high-level CI operations, enhanced canvas utilities, NAR management, and improved bulletin/state handling.

Key Changes:

  • Command-line interface with automatic help generation via Google Fire
  • CI operations module with 22 automation-focused functions for flow deployment and management
  • Enhanced canvas module with FlowFile inspection, state management, and verification capabilities
  • New bulletins and layout modules for improved flow organization
  • Extensions module for NAR lifecycle management with multi-version support

Reviewed changes

Copilot reviewed 71 out of 76 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
tests/test_layout.py Comprehensive layout module tests covering grid positioning, flow organization, and component alignment
tests/test_extensions.py NAR management tests including upload/delete roundtrips, multi-version workflows, and processor initialization
tests/test_cli.py CLI interface tests covering serialization, argument parsing, and integration with subprocess
tests/test_ci.py CI operations tests validating deployment, version control, and parameter management workflows
tests/test_canvas.py Enhanced canvas tests for process group creation, FlowFile inspection, state management, and config verification
tests/test_bulletins.py Bulletin retrieval and clearing tests with timestamp formatting utilities
tests/conftest.py Enhanced fixtures including NAR builders, state flow setup, and improved cleanup handling
resources/client_gen/swagger_templates/rest.mustache Binary content type support for asset uploads (octet-stream)
resources/client_gen/augmentations/nifi_processor_state_enum.py Processor state enum fix for transitional states
pyproject.toml CLI dependencies and pytest configuration
pylintrc Disabled duplicate-code warnings
nipyapi/versioning.py Git flow operations including save_git_flow_ver and get_local_modifications
nipyapi/utils.py New utilities: is_uuid, format_timestamp, binary file write support
nipyapi/registry/rest.py Binary content support for registry client
nipyapi/profiles.py Auto-resolution of profiles, enhanced environment variable handling
nipyapi/nifi/rest.py Binary content support for NiFi client

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Extract NiFi Registry functions to nipyapi.nifi_registry module
  with backwards-compatible shims in versioning.py
- Replace global cache with @lru_cache in conftest.py
- Clarify switch() usage in profiles.py error message
- Document UUID format-only validation in utils.py
- Fix URL validation in test_ci.py (use urlparse for hostname check)
@Chaffelson Chaffelson requested a review from Copilot December 30, 2025 10:08
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 70 out of 77 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@Chaffelson Chaffelson marked this pull request as ready for review December 30, 2025 10:30
@Chaffelson
Copy link
Owner Author

Chaffelson commented Dec 30, 2025

@ottobackwards I think this now has nearly all the operational functionality I'm using for flow authorship and operations automation in NiFi 2.7.2.
The CI functionality is largely being consumed in the nipyapi-actions repo, which has example workflows for both Gitlab and Github.

Copy link
Collaborator

@ottobackwards ottobackwards left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good. I cannot think of a reason not to land it and get it out there.
There are a lot of "magic" strings here, and some places where there are if else based operations that could be made into utility functions, but that can all be follow on as necessary.

@Chaffelson
Copy link
Owner Author

This looks good. I cannot think of a reason not to land it and get it out there. There are a lot of "magic" strings here, and some places where there are if else based operations that could be made into utility functions, but that can all be follow on as necessary.

Great, thanks - and good point about the redundancy. I'll create an issue to capture it for later work.

…rings

Bug fixes:
- canvas.py: Add _resolve_flowfile_cluster_node() helper for clustered NiFi
- canvas.py: get_flowfile_details/get_flowfile_content auto-resolve cluster_node_id
- canvas.py: peek_flowfiles preserves cluster_node_id from FlowFileSummaryDTO
- canvas.py: create_processor accepts string ID or ProcessGroupEntity
- verify_config.py: Remove fail_on_error param (always return result dict)

CLI improvements:
- cli.py: Use functools.wraps for proper signature preservation in fire
- canvas.py, layout.py, utils.py: Inline docstring format for CLI compatibility

Documentation:
- contributing.rst: Add CLI-specific docstring guidance

Tests:
- test_canvas.py: Add tests for cluster_node_id handling
- test_ci.py: Update tests for verify_config changes
…te_process_group

Previously, force deletion would delete each controller service individually,
which was slow and caused version control to show local modifications.
Now uses schedule_all_controllers() to bulk disable, which is faster and
non-destructive.
MapCacheServer binds to port 4557 and won't release it until disabled.
Without explicit cleanup, subsequent tests fail with 'Address already in use'
when trying to enable their own MapCacheServer.

Added finalizer to disable both server and client controllers before
fix_pg's finalizer runs to delete the process group.
…et state

Previously the function returned immediately after the API call, leaving
controllers in transitional states (ENABLING/DISABLING). This caused race
conditions in slower environments (e.g. Python 3.9) where callers would
check controller state before transitions completed.

Now uses wait_to_complete to poll until all controllers in the PG reach
the target state, consistent with schedule_controller behavior.
@Chaffelson Chaffelson merged commit c4127de into main Dec 31, 2025
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants