nvidia-nat 1.2.0rc5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aiq/agent/__init__.py +0 -0
- aiq/agent/base.py +239 -0
- aiq/agent/dual_node.py +67 -0
- aiq/agent/react_agent/__init__.py +0 -0
- aiq/agent/react_agent/agent.py +355 -0
- aiq/agent/react_agent/output_parser.py +104 -0
- aiq/agent/react_agent/prompt.py +41 -0
- aiq/agent/react_agent/register.py +149 -0
- aiq/agent/reasoning_agent/__init__.py +0 -0
- aiq/agent/reasoning_agent/reasoning_agent.py +225 -0
- aiq/agent/register.py +23 -0
- aiq/agent/rewoo_agent/__init__.py +0 -0
- aiq/agent/rewoo_agent/agent.py +411 -0
- aiq/agent/rewoo_agent/prompt.py +108 -0
- aiq/agent/rewoo_agent/register.py +158 -0
- aiq/agent/tool_calling_agent/__init__.py +0 -0
- aiq/agent/tool_calling_agent/agent.py +119 -0
- aiq/agent/tool_calling_agent/register.py +106 -0
- aiq/authentication/__init__.py +14 -0
- aiq/authentication/api_key/__init__.py +14 -0
- aiq/authentication/api_key/api_key_auth_provider.py +96 -0
- aiq/authentication/api_key/api_key_auth_provider_config.py +124 -0
- aiq/authentication/api_key/register.py +26 -0
- aiq/authentication/exceptions/__init__.py +14 -0
- aiq/authentication/exceptions/api_key_exceptions.py +38 -0
- aiq/authentication/http_basic_auth/__init__.py +0 -0
- aiq/authentication/http_basic_auth/http_basic_auth_provider.py +81 -0
- aiq/authentication/http_basic_auth/register.py +30 -0
- aiq/authentication/interfaces.py +93 -0
- aiq/authentication/oauth2/__init__.py +14 -0
- aiq/authentication/oauth2/oauth2_auth_code_flow_provider.py +107 -0
- aiq/authentication/oauth2/oauth2_auth_code_flow_provider_config.py +39 -0
- aiq/authentication/oauth2/register.py +25 -0
- aiq/authentication/register.py +21 -0
- aiq/builder/__init__.py +0 -0
- aiq/builder/builder.py +285 -0
- aiq/builder/component_utils.py +316 -0
- aiq/builder/context.py +264 -0
- aiq/builder/embedder.py +24 -0
- aiq/builder/eval_builder.py +161 -0
- aiq/builder/evaluator.py +29 -0
- aiq/builder/framework_enum.py +24 -0
- aiq/builder/front_end.py +73 -0
- aiq/builder/function.py +344 -0
- aiq/builder/function_base.py +380 -0
- aiq/builder/function_info.py +627 -0
- aiq/builder/intermediate_step_manager.py +174 -0
- aiq/builder/llm.py +25 -0
- aiq/builder/retriever.py +25 -0
- aiq/builder/user_interaction_manager.py +74 -0
- aiq/builder/workflow.py +148 -0
- aiq/builder/workflow_builder.py +1117 -0
- aiq/cli/__init__.py +14 -0
- aiq/cli/cli_utils/__init__.py +0 -0
- aiq/cli/cli_utils/config_override.py +231 -0
- aiq/cli/cli_utils/validation.py +37 -0
- aiq/cli/commands/__init__.py +0 -0
- aiq/cli/commands/configure/__init__.py +0 -0
- aiq/cli/commands/configure/channel/__init__.py +0 -0
- aiq/cli/commands/configure/channel/add.py +28 -0
- aiq/cli/commands/configure/channel/channel.py +36 -0
- aiq/cli/commands/configure/channel/remove.py +30 -0
- aiq/cli/commands/configure/channel/update.py +30 -0
- aiq/cli/commands/configure/configure.py +33 -0
- aiq/cli/commands/evaluate.py +139 -0
- aiq/cli/commands/info/__init__.py +14 -0
- aiq/cli/commands/info/info.py +39 -0
- aiq/cli/commands/info/list_channels.py +32 -0
- aiq/cli/commands/info/list_components.py +129 -0
- aiq/cli/commands/info/list_mcp.py +213 -0
- aiq/cli/commands/registry/__init__.py +14 -0
- aiq/cli/commands/registry/publish.py +88 -0
- aiq/cli/commands/registry/pull.py +118 -0
- aiq/cli/commands/registry/registry.py +38 -0
- aiq/cli/commands/registry/remove.py +108 -0
- aiq/cli/commands/registry/search.py +155 -0
- aiq/cli/commands/sizing/__init__.py +14 -0
- aiq/cli/commands/sizing/calc.py +297 -0
- aiq/cli/commands/sizing/sizing.py +27 -0
- aiq/cli/commands/start.py +246 -0
- aiq/cli/commands/uninstall.py +81 -0
- aiq/cli/commands/validate.py +47 -0
- aiq/cli/commands/workflow/__init__.py +14 -0
- aiq/cli/commands/workflow/templates/__init__.py.j2 +0 -0
- aiq/cli/commands/workflow/templates/config.yml.j2 +16 -0
- aiq/cli/commands/workflow/templates/pyproject.toml.j2 +22 -0
- aiq/cli/commands/workflow/templates/register.py.j2 +5 -0
- aiq/cli/commands/workflow/templates/workflow.py.j2 +36 -0
- aiq/cli/commands/workflow/workflow.py +37 -0
- aiq/cli/commands/workflow/workflow_commands.py +313 -0
- aiq/cli/entrypoint.py +135 -0
- aiq/cli/main.py +44 -0
- aiq/cli/register_workflow.py +488 -0
- aiq/cli/type_registry.py +1000 -0
- aiq/data_models/__init__.py +14 -0
- aiq/data_models/api_server.py +694 -0
- aiq/data_models/authentication.py +231 -0
- aiq/data_models/common.py +171 -0
- aiq/data_models/component.py +54 -0
- aiq/data_models/component_ref.py +168 -0
- aiq/data_models/config.py +406 -0
- aiq/data_models/dataset_handler.py +123 -0
- aiq/data_models/discovery_metadata.py +335 -0
- aiq/data_models/embedder.py +27 -0
- aiq/data_models/evaluate.py +127 -0
- aiq/data_models/evaluator.py +26 -0
- aiq/data_models/front_end.py +26 -0
- aiq/data_models/function.py +30 -0
- aiq/data_models/function_dependencies.py +72 -0
- aiq/data_models/interactive.py +246 -0
- aiq/data_models/intermediate_step.py +302 -0
- aiq/data_models/invocation_node.py +38 -0
- aiq/data_models/llm.py +27 -0
- aiq/data_models/logging.py +26 -0
- aiq/data_models/memory.py +27 -0
- aiq/data_models/object_store.py +44 -0
- aiq/data_models/profiler.py +54 -0
- aiq/data_models/registry_handler.py +26 -0
- aiq/data_models/retriever.py +30 -0
- aiq/data_models/retry_mixin.py +35 -0
- aiq/data_models/span.py +187 -0
- aiq/data_models/step_adaptor.py +64 -0
- aiq/data_models/streaming.py +33 -0
- aiq/data_models/swe_bench_model.py +54 -0
- aiq/data_models/telemetry_exporter.py +26 -0
- aiq/data_models/ttc_strategy.py +30 -0
- aiq/embedder/__init__.py +0 -0
- aiq/embedder/langchain_client.py +41 -0
- aiq/embedder/nim_embedder.py +59 -0
- aiq/embedder/openai_embedder.py +43 -0
- aiq/embedder/register.py +24 -0
- aiq/eval/__init__.py +14 -0
- aiq/eval/config.py +60 -0
- aiq/eval/dataset_handler/__init__.py +0 -0
- aiq/eval/dataset_handler/dataset_downloader.py +106 -0
- aiq/eval/dataset_handler/dataset_filter.py +52 -0
- aiq/eval/dataset_handler/dataset_handler.py +254 -0
- aiq/eval/evaluate.py +506 -0
- aiq/eval/evaluator/__init__.py +14 -0
- aiq/eval/evaluator/base_evaluator.py +73 -0
- aiq/eval/evaluator/evaluator_model.py +45 -0
- aiq/eval/intermediate_step_adapter.py +99 -0
- aiq/eval/rag_evaluator/__init__.py +0 -0
- aiq/eval/rag_evaluator/evaluate.py +178 -0
- aiq/eval/rag_evaluator/register.py +143 -0
- aiq/eval/register.py +23 -0
- aiq/eval/remote_workflow.py +133 -0
- aiq/eval/runners/__init__.py +14 -0
- aiq/eval/runners/config.py +39 -0
- aiq/eval/runners/multi_eval_runner.py +54 -0
- aiq/eval/runtime_event_subscriber.py +52 -0
- aiq/eval/swe_bench_evaluator/__init__.py +0 -0
- aiq/eval/swe_bench_evaluator/evaluate.py +215 -0
- aiq/eval/swe_bench_evaluator/register.py +36 -0
- aiq/eval/trajectory_evaluator/__init__.py +0 -0
- aiq/eval/trajectory_evaluator/evaluate.py +75 -0
- aiq/eval/trajectory_evaluator/register.py +40 -0
- aiq/eval/tunable_rag_evaluator/__init__.py +0 -0
- aiq/eval/tunable_rag_evaluator/evaluate.py +245 -0
- aiq/eval/tunable_rag_evaluator/register.py +52 -0
- aiq/eval/usage_stats.py +41 -0
- aiq/eval/utils/__init__.py +0 -0
- aiq/eval/utils/output_uploader.py +140 -0
- aiq/eval/utils/tqdm_position_registry.py +40 -0
- aiq/eval/utils/weave_eval.py +184 -0
- aiq/experimental/__init__.py +0 -0
- aiq/experimental/decorators/__init__.py +0 -0
- aiq/experimental/decorators/experimental_warning_decorator.py +130 -0
- aiq/experimental/test_time_compute/__init__.py +0 -0
- aiq/experimental/test_time_compute/editing/__init__.py +0 -0
- aiq/experimental/test_time_compute/editing/iterative_plan_refinement_editor.py +147 -0
- aiq/experimental/test_time_compute/editing/llm_as_a_judge_editor.py +204 -0
- aiq/experimental/test_time_compute/editing/motivation_aware_summarization.py +107 -0
- aiq/experimental/test_time_compute/functions/__init__.py +0 -0
- aiq/experimental/test_time_compute/functions/execute_score_select_function.py +105 -0
- aiq/experimental/test_time_compute/functions/its_tool_orchestration_function.py +205 -0
- aiq/experimental/test_time_compute/functions/its_tool_wrapper_function.py +146 -0
- aiq/experimental/test_time_compute/functions/plan_select_execute_function.py +224 -0
- aiq/experimental/test_time_compute/models/__init__.py +0 -0
- aiq/experimental/test_time_compute/models/editor_config.py +132 -0
- aiq/experimental/test_time_compute/models/scoring_config.py +112 -0
- aiq/experimental/test_time_compute/models/search_config.py +120 -0
- aiq/experimental/test_time_compute/models/selection_config.py +154 -0
- aiq/experimental/test_time_compute/models/stage_enums.py +43 -0
- aiq/experimental/test_time_compute/models/strategy_base.py +66 -0
- aiq/experimental/test_time_compute/models/tool_use_config.py +41 -0
- aiq/experimental/test_time_compute/models/ttc_item.py +48 -0
- aiq/experimental/test_time_compute/register.py +36 -0
- aiq/experimental/test_time_compute/scoring/__init__.py +0 -0
- aiq/experimental/test_time_compute/scoring/llm_based_agent_scorer.py +168 -0
- aiq/experimental/test_time_compute/scoring/llm_based_plan_scorer.py +168 -0
- aiq/experimental/test_time_compute/scoring/motivation_aware_scorer.py +111 -0
- aiq/experimental/test_time_compute/search/__init__.py +0 -0
- aiq/experimental/test_time_compute/search/multi_llm_planner.py +128 -0
- aiq/experimental/test_time_compute/search/multi_query_retrieval_search.py +122 -0
- aiq/experimental/test_time_compute/search/single_shot_multi_plan_planner.py +128 -0
- aiq/experimental/test_time_compute/selection/__init__.py +0 -0
- aiq/experimental/test_time_compute/selection/best_of_n_selector.py +63 -0
- aiq/experimental/test_time_compute/selection/llm_based_agent_output_selector.py +131 -0
- aiq/experimental/test_time_compute/selection/llm_based_output_merging_selector.py +159 -0
- aiq/experimental/test_time_compute/selection/llm_based_plan_selector.py +128 -0
- aiq/experimental/test_time_compute/selection/threshold_selector.py +58 -0
- aiq/front_ends/__init__.py +14 -0
- aiq/front_ends/console/__init__.py +14 -0
- aiq/front_ends/console/authentication_flow_handler.py +233 -0
- aiq/front_ends/console/console_front_end_config.py +32 -0
- aiq/front_ends/console/console_front_end_plugin.py +96 -0
- aiq/front_ends/console/register.py +25 -0
- aiq/front_ends/cron/__init__.py +14 -0
- aiq/front_ends/fastapi/__init__.py +14 -0
- aiq/front_ends/fastapi/auth_flow_handlers/__init__.py +0 -0
- aiq/front_ends/fastapi/auth_flow_handlers/http_flow_handler.py +27 -0
- aiq/front_ends/fastapi/auth_flow_handlers/websocket_flow_handler.py +107 -0
- aiq/front_ends/fastapi/fastapi_front_end_config.py +234 -0
- aiq/front_ends/fastapi/fastapi_front_end_controller.py +68 -0
- aiq/front_ends/fastapi/fastapi_front_end_plugin.py +116 -0
- aiq/front_ends/fastapi/fastapi_front_end_plugin_worker.py +1092 -0
- aiq/front_ends/fastapi/html_snippets/__init__.py +14 -0
- aiq/front_ends/fastapi/html_snippets/auth_code_grant_success.py +35 -0
- aiq/front_ends/fastapi/intermediate_steps_subscriber.py +80 -0
- aiq/front_ends/fastapi/job_store.py +183 -0
- aiq/front_ends/fastapi/main.py +72 -0
- aiq/front_ends/fastapi/message_handler.py +298 -0
- aiq/front_ends/fastapi/message_validator.py +345 -0
- aiq/front_ends/fastapi/register.py +25 -0
- aiq/front_ends/fastapi/response_helpers.py +195 -0
- aiq/front_ends/fastapi/step_adaptor.py +321 -0
- aiq/front_ends/mcp/__init__.py +14 -0
- aiq/front_ends/mcp/mcp_front_end_config.py +32 -0
- aiq/front_ends/mcp/mcp_front_end_plugin.py +93 -0
- aiq/front_ends/mcp/register.py +27 -0
- aiq/front_ends/mcp/tool_converter.py +242 -0
- aiq/front_ends/register.py +22 -0
- aiq/front_ends/simple_base/__init__.py +14 -0
- aiq/front_ends/simple_base/simple_front_end_plugin_base.py +54 -0
- aiq/llm/__init__.py +0 -0
- aiq/llm/aws_bedrock_llm.py +57 -0
- aiq/llm/nim_llm.py +46 -0
- aiq/llm/openai_llm.py +46 -0
- aiq/llm/register.py +23 -0
- aiq/llm/utils/__init__.py +14 -0
- aiq/llm/utils/env_config_value.py +94 -0
- aiq/llm/utils/error.py +17 -0
- aiq/memory/__init__.py +20 -0
- aiq/memory/interfaces.py +183 -0
- aiq/memory/models.py +112 -0
- aiq/meta/module_to_distro.json +3 -0
- aiq/meta/pypi.md +58 -0
- aiq/object_store/__init__.py +20 -0
- aiq/object_store/in_memory_object_store.py +76 -0
- aiq/object_store/interfaces.py +84 -0
- aiq/object_store/models.py +36 -0
- aiq/object_store/register.py +20 -0
- aiq/observability/__init__.py +14 -0
- aiq/observability/exporter/__init__.py +14 -0
- aiq/observability/exporter/base_exporter.py +449 -0
- aiq/observability/exporter/exporter.py +78 -0
- aiq/observability/exporter/file_exporter.py +33 -0
- aiq/observability/exporter/processing_exporter.py +322 -0
- aiq/observability/exporter/raw_exporter.py +52 -0
- aiq/observability/exporter/span_exporter.py +265 -0
- aiq/observability/exporter_manager.py +335 -0
- aiq/observability/mixin/__init__.py +14 -0
- aiq/observability/mixin/batch_config_mixin.py +26 -0
- aiq/observability/mixin/collector_config_mixin.py +23 -0
- aiq/observability/mixin/file_mixin.py +288 -0
- aiq/observability/mixin/file_mode.py +23 -0
- aiq/observability/mixin/resource_conflict_mixin.py +134 -0
- aiq/observability/mixin/serialize_mixin.py +61 -0
- aiq/observability/mixin/type_introspection_mixin.py +183 -0
- aiq/observability/processor/__init__.py +14 -0
- aiq/observability/processor/batching_processor.py +310 -0
- aiq/observability/processor/callback_processor.py +42 -0
- aiq/observability/processor/intermediate_step_serializer.py +28 -0
- aiq/observability/processor/processor.py +71 -0
- aiq/observability/register.py +96 -0
- aiq/observability/utils/__init__.py +14 -0
- aiq/observability/utils/dict_utils.py +236 -0
- aiq/observability/utils/time_utils.py +31 -0
- aiq/plugins/.namespace +1 -0
- aiq/profiler/__init__.py +0 -0
- aiq/profiler/calc/__init__.py +14 -0
- aiq/profiler/calc/calc_runner.py +627 -0
- aiq/profiler/calc/calculations.py +288 -0
- aiq/profiler/calc/data_models.py +188 -0
- aiq/profiler/calc/plot.py +345 -0
- aiq/profiler/callbacks/__init__.py +0 -0
- aiq/profiler/callbacks/agno_callback_handler.py +295 -0
- aiq/profiler/callbacks/base_callback_class.py +20 -0
- aiq/profiler/callbacks/langchain_callback_handler.py +290 -0
- aiq/profiler/callbacks/llama_index_callback_handler.py +205 -0
- aiq/profiler/callbacks/semantic_kernel_callback_handler.py +238 -0
- aiq/profiler/callbacks/token_usage_base_model.py +27 -0
- aiq/profiler/data_frame_row.py +51 -0
- aiq/profiler/data_models.py +24 -0
- aiq/profiler/decorators/__init__.py +0 -0
- aiq/profiler/decorators/framework_wrapper.py +131 -0
- aiq/profiler/decorators/function_tracking.py +254 -0
- aiq/profiler/forecasting/__init__.py +0 -0
- aiq/profiler/forecasting/config.py +18 -0
- aiq/profiler/forecasting/model_trainer.py +75 -0
- aiq/profiler/forecasting/models/__init__.py +22 -0
- aiq/profiler/forecasting/models/forecasting_base_model.py +40 -0
- aiq/profiler/forecasting/models/linear_model.py +196 -0
- aiq/profiler/forecasting/models/random_forest_regressor.py +268 -0
- aiq/profiler/inference_metrics_model.py +28 -0
- aiq/profiler/inference_optimization/__init__.py +0 -0
- aiq/profiler/inference_optimization/bottleneck_analysis/__init__.py +0 -0
- aiq/profiler/inference_optimization/bottleneck_analysis/nested_stack_analysis.py +460 -0
- aiq/profiler/inference_optimization/bottleneck_analysis/simple_stack_analysis.py +258 -0
- aiq/profiler/inference_optimization/data_models.py +386 -0
- aiq/profiler/inference_optimization/experimental/__init__.py +0 -0
- aiq/profiler/inference_optimization/experimental/concurrency_spike_analysis.py +468 -0
- aiq/profiler/inference_optimization/experimental/prefix_span_analysis.py +405 -0
- aiq/profiler/inference_optimization/llm_metrics.py +212 -0
- aiq/profiler/inference_optimization/prompt_caching.py +163 -0
- aiq/profiler/inference_optimization/token_uniqueness.py +107 -0
- aiq/profiler/inference_optimization/workflow_runtimes.py +72 -0
- aiq/profiler/intermediate_property_adapter.py +102 -0
- aiq/profiler/profile_runner.py +473 -0
- aiq/profiler/utils.py +184 -0
- aiq/registry_handlers/__init__.py +0 -0
- aiq/registry_handlers/local/__init__.py +0 -0
- aiq/registry_handlers/local/local_handler.py +176 -0
- aiq/registry_handlers/local/register_local.py +37 -0
- aiq/registry_handlers/metadata_factory.py +60 -0
- aiq/registry_handlers/package_utils.py +567 -0
- aiq/registry_handlers/pypi/__init__.py +0 -0
- aiq/registry_handlers/pypi/pypi_handler.py +251 -0
- aiq/registry_handlers/pypi/register_pypi.py +40 -0
- aiq/registry_handlers/register.py +21 -0
- aiq/registry_handlers/registry_handler_base.py +157 -0
- aiq/registry_handlers/rest/__init__.py +0 -0
- aiq/registry_handlers/rest/register_rest.py +56 -0
- aiq/registry_handlers/rest/rest_handler.py +237 -0
- aiq/registry_handlers/schemas/__init__.py +0 -0
- aiq/registry_handlers/schemas/headers.py +42 -0
- aiq/registry_handlers/schemas/package.py +68 -0
- aiq/registry_handlers/schemas/publish.py +63 -0
- aiq/registry_handlers/schemas/pull.py +82 -0
- aiq/registry_handlers/schemas/remove.py +36 -0
- aiq/registry_handlers/schemas/search.py +91 -0
- aiq/registry_handlers/schemas/status.py +47 -0
- aiq/retriever/__init__.py +0 -0
- aiq/retriever/interface.py +37 -0
- aiq/retriever/milvus/__init__.py +14 -0
- aiq/retriever/milvus/register.py +81 -0
- aiq/retriever/milvus/retriever.py +228 -0
- aiq/retriever/models.py +74 -0
- aiq/retriever/nemo_retriever/__init__.py +14 -0
- aiq/retriever/nemo_retriever/register.py +60 -0
- aiq/retriever/nemo_retriever/retriever.py +190 -0
- aiq/retriever/register.py +22 -0
- aiq/runtime/__init__.py +14 -0
- aiq/runtime/loader.py +215 -0
- aiq/runtime/runner.py +190 -0
- aiq/runtime/session.py +158 -0
- aiq/runtime/user_metadata.py +130 -0
- aiq/settings/__init__.py +0 -0
- aiq/settings/global_settings.py +318 -0
- aiq/test/.namespace +1 -0
- aiq/tool/__init__.py +0 -0
- aiq/tool/chat_completion.py +74 -0
- aiq/tool/code_execution/README.md +151 -0
- aiq/tool/code_execution/__init__.py +0 -0
- aiq/tool/code_execution/code_sandbox.py +267 -0
- aiq/tool/code_execution/local_sandbox/.gitignore +1 -0
- aiq/tool/code_execution/local_sandbox/Dockerfile.sandbox +60 -0
- aiq/tool/code_execution/local_sandbox/__init__.py +13 -0
- aiq/tool/code_execution/local_sandbox/local_sandbox_server.py +198 -0
- aiq/tool/code_execution/local_sandbox/sandbox.requirements.txt +6 -0
- aiq/tool/code_execution/local_sandbox/start_local_sandbox.sh +50 -0
- aiq/tool/code_execution/register.py +74 -0
- aiq/tool/code_execution/test_code_execution_sandbox.py +414 -0
- aiq/tool/code_execution/utils.py +100 -0
- aiq/tool/datetime_tools.py +42 -0
- aiq/tool/document_search.py +141 -0
- aiq/tool/github_tools/__init__.py +0 -0
- aiq/tool/github_tools/create_github_commit.py +133 -0
- aiq/tool/github_tools/create_github_issue.py +87 -0
- aiq/tool/github_tools/create_github_pr.py +106 -0
- aiq/tool/github_tools/get_github_file.py +106 -0
- aiq/tool/github_tools/get_github_issue.py +166 -0
- aiq/tool/github_tools/get_github_pr.py +256 -0
- aiq/tool/github_tools/update_github_issue.py +100 -0
- aiq/tool/mcp/__init__.py +14 -0
- aiq/tool/mcp/exceptions.py +142 -0
- aiq/tool/mcp/mcp_client.py +255 -0
- aiq/tool/mcp/mcp_tool.py +96 -0
- aiq/tool/memory_tools/__init__.py +0 -0
- aiq/tool/memory_tools/add_memory_tool.py +79 -0
- aiq/tool/memory_tools/delete_memory_tool.py +67 -0
- aiq/tool/memory_tools/get_memory_tool.py +72 -0
- aiq/tool/nvidia_rag.py +95 -0
- aiq/tool/register.py +38 -0
- aiq/tool/retriever.py +89 -0
- aiq/tool/server_tools.py +66 -0
- aiq/utils/__init__.py +0 -0
- aiq/utils/data_models/__init__.py +0 -0
- aiq/utils/data_models/schema_validator.py +58 -0
- aiq/utils/debugging_utils.py +43 -0
- aiq/utils/dump_distro_mapping.py +32 -0
- aiq/utils/exception_handlers/__init__.py +0 -0
- aiq/utils/exception_handlers/automatic_retries.py +289 -0
- aiq/utils/exception_handlers/mcp.py +211 -0
- aiq/utils/exception_handlers/schemas.py +114 -0
- aiq/utils/io/__init__.py +0 -0
- aiq/utils/io/model_processing.py +28 -0
- aiq/utils/io/yaml_tools.py +119 -0
- aiq/utils/log_utils.py +37 -0
- aiq/utils/metadata_utils.py +74 -0
- aiq/utils/optional_imports.py +142 -0
- aiq/utils/producer_consumer_queue.py +178 -0
- aiq/utils/reactive/__init__.py +0 -0
- aiq/utils/reactive/base/__init__.py +0 -0
- aiq/utils/reactive/base/observable_base.py +65 -0
- aiq/utils/reactive/base/observer_base.py +55 -0
- aiq/utils/reactive/base/subject_base.py +79 -0
- aiq/utils/reactive/observable.py +59 -0
- aiq/utils/reactive/observer.py +76 -0
- aiq/utils/reactive/subject.py +131 -0
- aiq/utils/reactive/subscription.py +49 -0
- aiq/utils/settings/__init__.py +0 -0
- aiq/utils/settings/global_settings.py +197 -0
- aiq/utils/string_utils.py +38 -0
- aiq/utils/type_converter.py +290 -0
- aiq/utils/type_utils.py +484 -0
- aiq/utils/url_utils.py +27 -0
- nvidia_nat-1.2.0rc5.dist-info/METADATA +363 -0
- nvidia_nat-1.2.0rc5.dist-info/RECORD +435 -0
- nvidia_nat-1.2.0rc5.dist-info/WHEEL +5 -0
- nvidia_nat-1.2.0rc5.dist-info/entry_points.txt +20 -0
- nvidia_nat-1.2.0rc5.dist-info/licenses/LICENSE-3rd-party.txt +3686 -0
- nvidia_nat-1.2.0rc5.dist-info/licenses/LICENSE.md +201 -0
- nvidia_nat-1.2.0rc5.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
import logging
|
|
17
|
+
import subprocess
|
|
18
|
+
from collections.abc import AsyncGenerator
|
|
19
|
+
from contextlib import asynccontextmanager
|
|
20
|
+
|
|
21
|
+
from aiq.data_models.component import AIQComponentEnum
|
|
22
|
+
from aiq.registry_handlers.registry_handler_base import AbstractRegistryHandler
|
|
23
|
+
from aiq.registry_handlers.schemas.package import PackageNameVersionList
|
|
24
|
+
from aiq.registry_handlers.schemas.publish import AIQArtifact
|
|
25
|
+
from aiq.registry_handlers.schemas.publish import PublishResponse
|
|
26
|
+
from aiq.registry_handlers.schemas.pull import PackageNameVersion
|
|
27
|
+
from aiq.registry_handlers.schemas.pull import PullRequestPackages
|
|
28
|
+
from aiq.registry_handlers.schemas.pull import PullResponse
|
|
29
|
+
from aiq.registry_handlers.schemas.remove import RemoveResponse
|
|
30
|
+
from aiq.registry_handlers.schemas.search import SearchQuery
|
|
31
|
+
from aiq.registry_handlers.schemas.search import SearchResponse
|
|
32
|
+
from aiq.registry_handlers.schemas.search import SearchResponseItem
|
|
33
|
+
from aiq.registry_handlers.schemas.status import ActionEnum
|
|
34
|
+
from aiq.registry_handlers.schemas.status import StatusEnum
|
|
35
|
+
|
|
36
|
+
logger = logging.getLogger(__name__)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class PypiRegistryHandler(AbstractRegistryHandler):
|
|
40
|
+
"""
|
|
41
|
+
A registry handler for interactions with a remote PyPI registry.
|
|
42
|
+
|
|
43
|
+
Built interfacing with this private PyPI server:
|
|
44
|
+
https://github.com/pypiserver/pypiserver
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
def __init__( # pylint: disable=R0917
|
|
48
|
+
self,
|
|
49
|
+
endpoint: str,
|
|
50
|
+
token: str | None = None,
|
|
51
|
+
publish_route: str = "",
|
|
52
|
+
pull_route: str = "",
|
|
53
|
+
search_route: str = ""):
|
|
54
|
+
super().__init__()
|
|
55
|
+
self._endpoint = endpoint.rstrip("/")
|
|
56
|
+
self._token = token
|
|
57
|
+
self._publish_route = publish_route.strip("/")
|
|
58
|
+
self._pull_route = pull_route.strip("/")
|
|
59
|
+
self._search_route = search_route.strip("/")
|
|
60
|
+
|
|
61
|
+
@asynccontextmanager
|
|
62
|
+
async def publish(self, artifact: AIQArtifact) -> AsyncGenerator[PublishResponse]:
|
|
63
|
+
"""Publishes an AIQ Toolkit artifact to a PyPI remote registry.
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
artifact (AIQArtifact): An artifact that contain AIQ Toolkit plugin wheel and it's corrosponding discovery
|
|
67
|
+
metadata.
|
|
68
|
+
|
|
69
|
+
Yields:
|
|
70
|
+
Iterator[AsyncGenerator[PublishResponse, None]]: A response message that includes a completion status
|
|
71
|
+
message.
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
try:
|
|
75
|
+
result = self._upload_to_pypi(wheel_path=artifact.whl_path)
|
|
76
|
+
result.check_returncode()
|
|
77
|
+
|
|
78
|
+
validated_publish_response = PublishResponse(status={
|
|
79
|
+
"status": StatusEnum.SUCCESS, "message": "", "action": ActionEnum.PUBLISH
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
yield validated_publish_response
|
|
83
|
+
|
|
84
|
+
except Exception as e:
|
|
85
|
+
msg = f"Error publishing package: {e}"
|
|
86
|
+
validated_publish_response = PublishResponse(status={
|
|
87
|
+
"status": StatusEnum.ERROR, "message": msg, "action": ActionEnum.PUBLISH
|
|
88
|
+
})
|
|
89
|
+
logger.exception(validated_publish_response.status.message, exc_info=True)
|
|
90
|
+
|
|
91
|
+
yield validated_publish_response
|
|
92
|
+
|
|
93
|
+
finally:
|
|
94
|
+
logger.info("Execution complete.")
|
|
95
|
+
|
|
96
|
+
def _upload_to_pypi(self, wheel_path: str) -> None:
|
|
97
|
+
|
|
98
|
+
return subprocess.run(
|
|
99
|
+
["twine", "upload", "--repository-url", f"{self._endpoint}/{self._publish_route}", f"{wheel_path}"],
|
|
100
|
+
check=True)
|
|
101
|
+
|
|
102
|
+
@asynccontextmanager
|
|
103
|
+
async def pull(self, packages: PullRequestPackages) -> AsyncGenerator[PullResponse]:
|
|
104
|
+
"""Download and install AIQ Toolkit artifacts from a remote PyPI remote registry.
|
|
105
|
+
|
|
106
|
+
Args:
|
|
107
|
+
packages (PullRequestPackages): Parameters used to pull the AIQ Toolkit artifact.
|
|
108
|
+
|
|
109
|
+
Yields:
|
|
110
|
+
Iterator[AsyncGenerator[PullResponse, None]]: A response message that includes a the pulled packages and a
|
|
111
|
+
completion status message.
|
|
112
|
+
"""
|
|
113
|
+
|
|
114
|
+
try:
|
|
115
|
+
versioned_packages = []
|
|
116
|
+
for package in packages.packages:
|
|
117
|
+
|
|
118
|
+
if isinstance(package, PackageNameVersion):
|
|
119
|
+
if (hasattr(package, "version") and package.version is not None):
|
|
120
|
+
versioned_package = f"{package.name}=={package.version}"
|
|
121
|
+
else:
|
|
122
|
+
versioned_package = package.name
|
|
123
|
+
versioned_packages.append(versioned_package)
|
|
124
|
+
else:
|
|
125
|
+
versioned_packages.append(package.whl_path)
|
|
126
|
+
|
|
127
|
+
versioned_packages_str = " ".join(versioned_packages)
|
|
128
|
+
|
|
129
|
+
result = subprocess.run(
|
|
130
|
+
[
|
|
131
|
+
"uv",
|
|
132
|
+
"pip",
|
|
133
|
+
"install",
|
|
134
|
+
"--prerelease=allow",
|
|
135
|
+
"--index-url",
|
|
136
|
+
f"{self._endpoint}/{self._pull_route}/",
|
|
137
|
+
versioned_packages_str
|
|
138
|
+
], # pylint: disable=W0631
|
|
139
|
+
check=True)
|
|
140
|
+
|
|
141
|
+
result.check_returncode()
|
|
142
|
+
|
|
143
|
+
validated_pull_response = PullResponse(status={
|
|
144
|
+
"status": StatusEnum.SUCCESS, "message": "", "action": ActionEnum.PULL
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
yield validated_pull_response
|
|
148
|
+
|
|
149
|
+
except Exception as e:
|
|
150
|
+
msg = f"Error pulling packages: {e}"
|
|
151
|
+
validated_pull_response = PullResponse(status={
|
|
152
|
+
"status": StatusEnum.ERROR, "message": msg, "action": ActionEnum.PULL
|
|
153
|
+
})
|
|
154
|
+
logger.exception(validated_pull_response.status.message, exc_info=True)
|
|
155
|
+
|
|
156
|
+
yield validated_pull_response
|
|
157
|
+
|
|
158
|
+
finally:
|
|
159
|
+
logger.info("Execution complete.")
|
|
160
|
+
|
|
161
|
+
@asynccontextmanager
|
|
162
|
+
async def search(self, query: SearchQuery) -> AsyncGenerator[SearchResponse]:
|
|
163
|
+
"""Searches a remote PyPI registry for relevant AIQ Toolkit components.
|
|
164
|
+
|
|
165
|
+
Args:
|
|
166
|
+
query (SearchQuery): Parameters of the search to be performed.
|
|
167
|
+
|
|
168
|
+
Yields:
|
|
169
|
+
Iterator[AsyncGenerator[SearchResponse]]: A response message that includes search
|
|
170
|
+
parameters and a completion status message.
|
|
171
|
+
"""
|
|
172
|
+
|
|
173
|
+
try:
|
|
174
|
+
completed_process = subprocess.run(
|
|
175
|
+
["pip", "search", "--index", f"{self._endpoint}", query.query], # pylint: disable=W0631
|
|
176
|
+
text=True,
|
|
177
|
+
capture_output=True,
|
|
178
|
+
check=True)
|
|
179
|
+
search_response_list = []
|
|
180
|
+
search_results = completed_process.stdout
|
|
181
|
+
package_results = search_results.split("\n")
|
|
182
|
+
|
|
183
|
+
for package_result in package_results:
|
|
184
|
+
|
|
185
|
+
# Filter out empty and nested values
|
|
186
|
+
if ((package_result == "") or (package_result[0] == " ")):
|
|
187
|
+
continue
|
|
188
|
+
|
|
189
|
+
package_split = package_result.split(" ")
|
|
190
|
+
package = package_split[0]
|
|
191
|
+
version = package_split[1][1:-1]
|
|
192
|
+
|
|
193
|
+
search_resp_item = SearchResponseItem(package=package,
|
|
194
|
+
version=version,
|
|
195
|
+
component_type=AIQComponentEnum.PACKAGE,
|
|
196
|
+
component_name=package,
|
|
197
|
+
description="",
|
|
198
|
+
developer_notes="")
|
|
199
|
+
|
|
200
|
+
if (search_resp_item not in search_response_list):
|
|
201
|
+
search_response_list.append(search_resp_item)
|
|
202
|
+
|
|
203
|
+
if (len(search_response_list) > query.top_k):
|
|
204
|
+
break
|
|
205
|
+
|
|
206
|
+
validated_search_response = SearchResponse(results=search_response_list,
|
|
207
|
+
params=query,
|
|
208
|
+
status={
|
|
209
|
+
"status": StatusEnum.SUCCESS,
|
|
210
|
+
"message": "",
|
|
211
|
+
"action": ActionEnum.SEARCH
|
|
212
|
+
})
|
|
213
|
+
|
|
214
|
+
yield validated_search_response
|
|
215
|
+
|
|
216
|
+
except Exception as e:
|
|
217
|
+
msg = f"Error searching for artifacts: {e}"
|
|
218
|
+
logger.exception(msg, exc_info=True)
|
|
219
|
+
validated_search_response = SearchResponse(params=query,
|
|
220
|
+
status={
|
|
221
|
+
"status": StatusEnum.ERROR,
|
|
222
|
+
"message": msg,
|
|
223
|
+
"action": ActionEnum.SEARCH
|
|
224
|
+
})
|
|
225
|
+
|
|
226
|
+
yield validated_search_response
|
|
227
|
+
|
|
228
|
+
finally:
|
|
229
|
+
logger.info("Execution complete.")
|
|
230
|
+
|
|
231
|
+
@asynccontextmanager
|
|
232
|
+
async def remove(self, packages: PackageNameVersionList) -> AsyncGenerator[SearchResponse]:
|
|
233
|
+
"""Removes packages from a remote registry.
|
|
234
|
+
|
|
235
|
+
Args:
|
|
236
|
+
packages (PackageNameVersionList): The list of packages to remove.
|
|
237
|
+
|
|
238
|
+
Yields:
|
|
239
|
+
Iterator[AsyncGenerator[RemoveResponse]]: A response message that includes the packages and a
|
|
240
|
+
completion status message.
|
|
241
|
+
"""
|
|
242
|
+
|
|
243
|
+
try:
|
|
244
|
+
msg = "PyPI remove not supported."
|
|
245
|
+
validated_remove_response = RemoveResponse(status={
|
|
246
|
+
"status": StatusEnum.ERROR, "message": msg, "action": ActionEnum.REMOVE
|
|
247
|
+
})
|
|
248
|
+
|
|
249
|
+
yield validated_remove_response
|
|
250
|
+
finally:
|
|
251
|
+
logger.warning(validated_remove_response.status.message)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
from pydantic import Field
|
|
17
|
+
|
|
18
|
+
from aiq.cli.register_workflow import register_registry_handler
|
|
19
|
+
from aiq.data_models.registry_handler import RegistryHandlerBaseConfig
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class PypiRegistryHandlerConfig(RegistryHandlerBaseConfig, name="pypi"):
|
|
23
|
+
"""Registry handler for interacting with a remote PyPI registry index."""
|
|
24
|
+
|
|
25
|
+
endpoint: str = Field(description="A string representing the remote endpoint.")
|
|
26
|
+
token: str | None = Field(default=None,
|
|
27
|
+
description="The authentication token to use when interacting with the registry.")
|
|
28
|
+
publish_route: str = Field(description="The route to the AIQ Toolkit publish service.")
|
|
29
|
+
pull_route: str = Field(description="The route to the AIQ Toolkit pull service.")
|
|
30
|
+
search_route: str = Field(default="simple", description="The route to the AIQ Toolkit search service.")
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@register_registry_handler(config_type=PypiRegistryHandlerConfig)
|
|
34
|
+
async def pypi_publish_registry_handler(config: PypiRegistryHandlerConfig):
|
|
35
|
+
|
|
36
|
+
from aiq.registry_handlers.pypi.pypi_handler import PypiRegistryHandler
|
|
37
|
+
|
|
38
|
+
registry_handler = PypiRegistryHandler(endpoint=config.endpoint, token=config.token)
|
|
39
|
+
|
|
40
|
+
yield registry_handler
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
# pylint: disable=unused-import
|
|
17
|
+
# flake8: noqa
|
|
18
|
+
|
|
19
|
+
from .local import register_local # pylint: disable=E0611
|
|
20
|
+
from .pypi import register_pypi # pylint: disable=E0611
|
|
21
|
+
from .rest import register_rest # pylint: disable=E0611
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
from abc import ABC
|
|
17
|
+
from abc import abstractmethod
|
|
18
|
+
from collections.abc import AsyncGenerator
|
|
19
|
+
from contextlib import asynccontextmanager
|
|
20
|
+
from enum import Enum
|
|
21
|
+
|
|
22
|
+
from aiq.data_models.component import AIQComponentEnum
|
|
23
|
+
from aiq.data_models.discovery_metadata import DiscoveryMetadata
|
|
24
|
+
from aiq.registry_handlers.schemas.package import PackageNameVersionList
|
|
25
|
+
from aiq.registry_handlers.schemas.publish import AIQArtifact
|
|
26
|
+
from aiq.registry_handlers.schemas.publish import PublishResponse
|
|
27
|
+
from aiq.registry_handlers.schemas.pull import PullRequestPackages
|
|
28
|
+
from aiq.registry_handlers.schemas.pull import PullResponse
|
|
29
|
+
from aiq.registry_handlers.schemas.remove import RemoveResponse
|
|
30
|
+
from aiq.registry_handlers.schemas.search import SearchQuery
|
|
31
|
+
from aiq.registry_handlers.schemas.search import SearchResponse
|
|
32
|
+
from aiq.registry_handlers.schemas.search import VisualizeFields
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class AbstractRegistryHandler(ABC):
|
|
36
|
+
"""Base class outlining the interfaces for remote AIQ Toolkit registry interactions."""
|
|
37
|
+
|
|
38
|
+
def __init__(self):
|
|
39
|
+
self._discovery_metadata: dict[AIQComponentEnum, list[dict | DiscoveryMetadata]] = {}
|
|
40
|
+
self._aiq_artifact: AIQArtifact | None = None
|
|
41
|
+
self._whl_bytes: bytes
|
|
42
|
+
self._whl_path: str
|
|
43
|
+
self._whl_base64: str
|
|
44
|
+
|
|
45
|
+
@abstractmethod
|
|
46
|
+
@asynccontextmanager
|
|
47
|
+
async def publish(self, artifact: AIQArtifact) -> AsyncGenerator[PublishResponse]:
|
|
48
|
+
"""Publishes an AIQ Toolkit artifact to a remote registry.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
artifact (AIQArtifact): An artifact that contain AIQ Toolkit plugin wheel and it's corrosponding discovery
|
|
52
|
+
metadata.
|
|
53
|
+
|
|
54
|
+
Yields:
|
|
55
|
+
Iterator[AsyncGenerator[PublishResponse, None]]: A response message that includes a completion status
|
|
56
|
+
message.
|
|
57
|
+
"""
|
|
58
|
+
|
|
59
|
+
pass
|
|
60
|
+
|
|
61
|
+
@abstractmethod
|
|
62
|
+
@asynccontextmanager
|
|
63
|
+
async def pull(self, packages: PullRequestPackages) -> AsyncGenerator[PullResponse]:
|
|
64
|
+
"""Download and install AIQ Toolkit artifacts from a remote registry.
|
|
65
|
+
|
|
66
|
+
Args:
|
|
67
|
+
packages (PullRequestPackages): Parameters used to pull the AIQ Toolkit artifact.
|
|
68
|
+
|
|
69
|
+
Yields:
|
|
70
|
+
Iterator[AsyncGenerator[PullResponse]]: A response message that includes a the pulled packages and a
|
|
71
|
+
completion status message.
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
pass
|
|
75
|
+
|
|
76
|
+
@abstractmethod
|
|
77
|
+
@asynccontextmanager
|
|
78
|
+
async def search(self, query: SearchQuery) -> AsyncGenerator[SearchResponse]:
|
|
79
|
+
"""Searches the local aiq registry for relevant AIQ Toolkit components.
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
query (SearchQuery): Parameters of the search to be performed.
|
|
83
|
+
|
|
84
|
+
Yields:
|
|
85
|
+
Iterator[AsyncGenerator[SearchResponse]]: A response message that includes search
|
|
86
|
+
parameters and a completion status message.
|
|
87
|
+
"""
|
|
88
|
+
|
|
89
|
+
pass
|
|
90
|
+
|
|
91
|
+
@abstractmethod
|
|
92
|
+
@asynccontextmanager
|
|
93
|
+
async def remove(self, packages: PackageNameVersionList) -> AsyncGenerator[RemoveResponse]:
|
|
94
|
+
"""Removes packages from a remote registry.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
packages (PackageNameVersionList): The list of packages to remove.
|
|
98
|
+
|
|
99
|
+
Yields:
|
|
100
|
+
Iterator[AsyncGenerator[RemoveResponse]]: A response message that includes the packages and a
|
|
101
|
+
completion status message.
|
|
102
|
+
"""
|
|
103
|
+
|
|
104
|
+
pass
|
|
105
|
+
|
|
106
|
+
@staticmethod
|
|
107
|
+
def visualize_search_results(search_response: SearchResponse, pager: bool = True) -> None:
|
|
108
|
+
"""Visualze search results in a system terminal.
|
|
109
|
+
|
|
110
|
+
Args:
|
|
111
|
+
search_response (SearchResponse): A response message that includes search parameters and a completion status
|
|
112
|
+
message.
|
|
113
|
+
|
|
114
|
+
pager (bool, optional): Include an pagable terminal interface for large search results. Defaults to False.
|
|
115
|
+
"""
|
|
116
|
+
|
|
117
|
+
from rich.console import Console
|
|
118
|
+
from rich.table import Table
|
|
119
|
+
from rich.text import Text
|
|
120
|
+
|
|
121
|
+
table = Table(title="AIQ Toolkit Search Results", padding=(0, 1), show_lines=True)
|
|
122
|
+
for column in VisualizeFields:
|
|
123
|
+
table.add_column(column.value)
|
|
124
|
+
|
|
125
|
+
for result in search_response.results:
|
|
126
|
+
row = []
|
|
127
|
+
for column in VisualizeFields:
|
|
128
|
+
value = getattr(result, column.value)
|
|
129
|
+
if isinstance(value, Enum):
|
|
130
|
+
value = value.value
|
|
131
|
+
text = Text(value, overflow="fold")
|
|
132
|
+
row.append(text)
|
|
133
|
+
table.add_row(*row, style='bright_green')
|
|
134
|
+
|
|
135
|
+
console = Console()
|
|
136
|
+
|
|
137
|
+
if (pager):
|
|
138
|
+
with console.pager():
|
|
139
|
+
console.print(table)
|
|
140
|
+
else:
|
|
141
|
+
console.print(table)
|
|
142
|
+
|
|
143
|
+
@staticmethod
|
|
144
|
+
def save_search_results(search_response: SearchResponse, save_path: str) -> None:
|
|
145
|
+
"""Save search results to a local json file.
|
|
146
|
+
|
|
147
|
+
Args:
|
|
148
|
+
search_response (SearchResponse): A response message that includes search parameters and a completion status
|
|
149
|
+
message.
|
|
150
|
+
|
|
151
|
+
save_path (str): The path to save the json search results.
|
|
152
|
+
"""
|
|
153
|
+
|
|
154
|
+
search_response_str = search_response.model_dump_json(indent=4)
|
|
155
|
+
|
|
156
|
+
with open(save_path, "w", encoding="utf-8") as f:
|
|
157
|
+
f.write(search_response_str)
|
|
File without changes
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
import os
|
|
17
|
+
|
|
18
|
+
from pydantic import Field
|
|
19
|
+
|
|
20
|
+
from aiq.cli.register_workflow import register_registry_handler
|
|
21
|
+
from aiq.data_models.registry_handler import RegistryHandlerBaseConfig
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class RestRegistryHandlerConfig(RegistryHandlerBaseConfig, name="rest"):
|
|
25
|
+
"""Registry handler for interacting with a remote REST registry."""
|
|
26
|
+
|
|
27
|
+
endpoint: str = Field(description="A string representing the remote endpoint.")
|
|
28
|
+
token: str | None = Field(default=None,
|
|
29
|
+
description="The authentication token to use when interacting with the registry.")
|
|
30
|
+
publish_route: str = Field(default="", description="The route to the AIQ Toolkit publish service.")
|
|
31
|
+
pull_route: str = Field(default="", description="The route to the AIQ Toolkit pull service.")
|
|
32
|
+
search_route: str = Field(default="", description="The route to the AIQ Toolkit search service")
|
|
33
|
+
remove_route: str = Field(default="", description="The route to the AIQ Toolkit remove service")
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@register_registry_handler(config_type=RestRegistryHandlerConfig)
|
|
37
|
+
async def rest_search_handler(config: RestRegistryHandlerConfig):
|
|
38
|
+
|
|
39
|
+
from aiq.registry_handlers.rest.rest_handler import RestRegistryHandler
|
|
40
|
+
|
|
41
|
+
if (config.token is None):
|
|
42
|
+
registry_token = os.getenv("REGISTRY_TOKEN")
|
|
43
|
+
|
|
44
|
+
if (registry_token is None):
|
|
45
|
+
raise ValueError("Please supply registry token.")
|
|
46
|
+
else:
|
|
47
|
+
registry_token = config.token
|
|
48
|
+
|
|
49
|
+
registry_handler = RestRegistryHandler(token=registry_token,
|
|
50
|
+
endpoint=config.endpoint,
|
|
51
|
+
publish_route=config.publish_route,
|
|
52
|
+
pull_route=config.pull_route,
|
|
53
|
+
search_route=config.search_route,
|
|
54
|
+
remove_route=config.remove_route)
|
|
55
|
+
|
|
56
|
+
yield registry_handler
|