uipath 2.0.67__tar.gz → 2.0.69__tar.gz
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.
Potentially problematic release.
This version of uipath might be problematic. Click here for more details.
- {uipath-2.0.67 → uipath-2.0.69}/PKG-INFO +1 -1
- {uipath-2.0.67 → uipath-2.0.69}/pyproject.toml +1 -1
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_services/context_grounding_service.py +11 -4
- uipath-2.0.69/src/uipath/_services/folder_service.py +85 -0
- {uipath-2.0.67 → uipath-2.0.69}/tests/sdk/services/test_context_grounding_service.py +18 -13
- uipath-2.0.69/tests/sdk/services/test_folder_service.py +370 -0
- {uipath-2.0.67 → uipath-2.0.69}/uv.lock +1698 -1697
- uipath-2.0.67/src/uipath/_services/folder_service.py +0 -52
- uipath-2.0.67/tests/sdk/services/test_folder_service.py +0 -173
- {uipath-2.0.67 → uipath-2.0.69}/.cursorrules +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/.editorconfig +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/.gitattributes +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/.github/workflows/cd.yml +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/.github/workflows/ci.yml +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/.github/workflows/commitlint.yml +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/.github/workflows/lint.yml +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/.github/workflows/publish-dev.yml +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/.github/workflows/publish-docs.yml +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/.github/workflows/slack.yml +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/.github/workflows/test.yml +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/.gitignore +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/.pre-commit-config.yaml +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/.python-version +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/.vscode/extensions.json +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/.vscode/launch.json +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/.vscode/settings.json +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/CONTRIBUTING.md +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/LICENSE +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/README.md +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/docs/CONTRIBUTING.md +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/docs/FAQ.md +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/docs/assets/env-preparation-failed-dark.png +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/docs/assets/env-preparation-failed-light.png +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/docs/assets/favicon.png +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/docs/assets/logo-dark.svg +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/docs/assets/logo-light.svg +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/docs/cli/index.md +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/docs/core/actions.md +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/docs/core/assets/cloud_env_var_dark.gif +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/docs/core/assets/cloud_env_var_light.gif +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/docs/core/assets/cloud_env_var_secret_dark.png +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/docs/core/assets/cloud_env_var_secret_light.png +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/docs/core/assets/copy_path_dark.png +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/docs/core/assets/copy_path_light.png +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/docs/core/assets.md +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/docs/core/attachments.md +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/docs/core/buckets.md +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/docs/core/connections.md +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/docs/core/context_grounding.md +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/docs/core/environment_variables.md +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/docs/core/getting_started.md +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/docs/core/jobs.md +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/docs/core/processes.md +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/docs/core/queues.md +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/docs/core/traced.md +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/docs/hooks.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/docs/javascripts/extra.js +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/docs/langchain/chat_models.md +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/docs/langchain/context_grounding.md +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/docs/langchain/human_in_the_loop.md +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/docs/overrides/main.html +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/docs/overrides/partials/actions.html +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/docs/overrides/partials/logo.html +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/docs/release_policy.md +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/docs/stylesheets/extra.css +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/justfile +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/mkdocs.yml +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/py.typed +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/__init__.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_cli/README.md +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_cli/__init__.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_cli/_auth/_auth_server.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_cli/_auth/_models.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_cli/_auth/_oidc_utils.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_cli/_auth/_portal_service.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_cli/_auth/_utils.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_cli/_auth/auth_config.json +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_cli/_auth/index.html +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_cli/_auth/localhost.crt +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_cli/_auth/localhost.key +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_cli/_runtime/_contracts.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_cli/_runtime/_escalation.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_cli/_runtime/_hitl.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_cli/_runtime/_logging.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_cli/_runtime/_runtime.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_cli/_templates/.psmdcp.template +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_cli/_templates/.rels.template +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_cli/_templates/[Content_Types].xml.template +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_cli/_templates/main.py.template +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_cli/_templates/package.nuspec.template +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_cli/_utils/_common.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_cli/_utils/_console.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_cli/_utils/_constants.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_cli/_utils/_debug.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_cli/_utils/_folders.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_cli/_utils/_input_args.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_cli/_utils/_parse_ast.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_cli/_utils/_processes.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_cli/_utils/_tracing.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_cli/cli_auth.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_cli/cli_deploy.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_cli/cli_init.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_cli/cli_invoke.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_cli/cli_new.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_cli/cli_pack.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_cli/cli_publish.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_cli/cli_run.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_cli/middlewares.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_cli/spinner.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_config.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_execution_context.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_folder_context.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_services/__init__.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_services/_base_service.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_services/actions_service.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_services/api_client.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_services/assets_service.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_services/attachments_service.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_services/buckets_service.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_services/connections_service.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_services/jobs_service.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_services/llm_gateway_service.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_services/processes_service.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_services/queues_service.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_uipath.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_utils/__init__.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_utils/_endpoint.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_utils/_infer_bindings.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_utils/_logs.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_utils/_read_overwrites.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_utils/_request_override.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_utils/_request_spec.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_utils/_url.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_utils/_user_agent.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/_utils/constants.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/models/__init__.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/models/action_schema.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/models/actions.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/models/assets.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/models/attachment.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/models/buckets.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/models/connections.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/models/context_grounding.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/models/context_grounding_index.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/models/errors.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/models/exceptions.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/models/interrupt_models.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/models/job.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/models/llm_gateway.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/models/processes.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/models/queues.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/py.typed +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/telemetry/__init__.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/telemetry/_constants.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/telemetry/_track.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/tracing/__init__.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/tracing/_otel_exporters.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/tracing/_traced.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/src/uipath/tracing/_utils.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/tests/__init__.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/tests/cli/conftest.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/tests/cli/mocks/bindings_script.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/tests/cli/mocks/pyproject.toml +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/tests/cli/mocks/simple_script.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/tests/cli/mocks/uipath-mock.json +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/tests/cli/mocks/uipath-simple-script-mock.json +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/tests/cli/test_hitl.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/tests/cli/test_init.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/tests/cli/test_invoke.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/tests/cli/test_new.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/tests/cli/test_pack.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/tests/cli/test_publish.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/tests/cli/test_run.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/tests/cli/test_utils.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/tests/cli/utils/project_details.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/tests/cli/utils/uipath_json.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/tests/conftest.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/tests/sdk/services/conftest.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/tests/sdk/services/test_actions_service.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/tests/sdk/services/test_api_client.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/tests/sdk/services/test_assets_service.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/tests/sdk/services/test_attachments_service.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/tests/sdk/services/test_base_service.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/tests/sdk/services/test_buckets_service.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/tests/sdk/services/test_connections_service.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/tests/sdk/services/test_jobs_service.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/tests/sdk/services/test_llm_integration.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/tests/sdk/services/test_llm_service.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/tests/sdk/services/test_processes_service.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/tests/sdk/services/test_queues_service.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/tests/sdk/services/test_uipath_llm_integration.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/tests/sdk/test_bindings_inference.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/tests/sdk/test_config.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/tests/sdk/test_overwrites.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/tests/tracing/test_otel_exporters.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/tests/tracing/test_span_utils.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/tests/tracing/test_traced.py +0 -0
- {uipath-2.0.67 → uipath-2.0.69}/tests/tracing/test_tracing_manager.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: uipath
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.69
|
|
4
4
|
Summary: Python SDK and CLI for UiPath Platform, enabling programmatic interaction with automation services, process management, and deployment tools.
|
|
5
5
|
Project-URL: Homepage, https://uipath.com
|
|
6
6
|
Project-URL: Repository, https://github.com/UiPath/uipath-python
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "uipath"
|
|
3
|
-
version = "2.0.
|
|
3
|
+
version = "2.0.69"
|
|
4
4
|
description = "Python SDK and CLI for UiPath Platform, enabling programmatic interaction with automation services, process management, and deployment tools."
|
|
5
5
|
readme = { file = "README.md", content-type = "text/markdown" }
|
|
6
6
|
requires-python = ">=3.10"
|
|
@@ -56,6 +56,7 @@ class ContextGroundingService(FolderContext, BaseService):
|
|
|
56
56
|
source_path: Optional[str] = None,
|
|
57
57
|
folder_key: Optional[str] = None,
|
|
58
58
|
folder_path: Optional[str] = None,
|
|
59
|
+
ingest_data: bool = True,
|
|
59
60
|
) -> None:
|
|
60
61
|
"""Add content to the index.
|
|
61
62
|
|
|
@@ -67,6 +68,7 @@ class ContextGroundingService(FolderContext, BaseService):
|
|
|
67
68
|
source_path (Optional[str]): The source path of the content if it is being uploaded from a file.
|
|
68
69
|
folder_key (Optional[str]): The key of the folder where the index resides.
|
|
69
70
|
folder_path (Optional[str]): The path of the folder where the index resides.
|
|
71
|
+
ingest_data (bool): Whether to ingest data in the index after content is uploaded. Defaults to True.
|
|
70
72
|
|
|
71
73
|
Raises:
|
|
72
74
|
ValueError: If neither content nor source_path is provided, or if both are provided.
|
|
@@ -94,7 +96,9 @@ class ContextGroundingService(FolderContext, BaseService):
|
|
|
94
96
|
folder_path=bucket_folder_path,
|
|
95
97
|
content_type=content_type,
|
|
96
98
|
)
|
|
97
|
-
|
|
99
|
+
|
|
100
|
+
if ingest_data:
|
|
101
|
+
self.ingest_data(index, folder_key=folder_key, folder_path=folder_path)
|
|
98
102
|
|
|
99
103
|
@traced(name="add_to_index", run_type="uipath")
|
|
100
104
|
@infer_bindings(resource_type="index")
|
|
@@ -107,6 +111,7 @@ class ContextGroundingService(FolderContext, BaseService):
|
|
|
107
111
|
source_path: Optional[str] = None,
|
|
108
112
|
folder_key: Optional[str] = None,
|
|
109
113
|
folder_path: Optional[str] = None,
|
|
114
|
+
ingest_data: bool = True,
|
|
110
115
|
) -> None:
|
|
111
116
|
"""Asynchronously add content to the index.
|
|
112
117
|
|
|
@@ -118,6 +123,7 @@ class ContextGroundingService(FolderContext, BaseService):
|
|
|
118
123
|
source_path (Optional[str]): The source path of the content if it is being uploaded from a file.
|
|
119
124
|
folder_key (Optional[str]): The key of the folder where the index resides.
|
|
120
125
|
folder_path (Optional[str]): The path of the folder where the index resides.
|
|
126
|
+
ingest_data (bool): Whether to ingest data in the index after content is uploaded. Defaults to True.
|
|
121
127
|
|
|
122
128
|
Raises:
|
|
123
129
|
ValueError: If neither content nor source_path is provided, or if both are provided.
|
|
@@ -148,9 +154,10 @@ class ContextGroundingService(FolderContext, BaseService):
|
|
|
148
154
|
content_type=content_type,
|
|
149
155
|
)
|
|
150
156
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
157
|
+
if ingest_data:
|
|
158
|
+
await self.ingest_data_async(
|
|
159
|
+
index, folder_key=folder_key, folder_path=folder_path
|
|
160
|
+
)
|
|
154
161
|
|
|
155
162
|
@traced(name="contextgrounding_retrieve", run_type="uipath")
|
|
156
163
|
@infer_bindings(resource_type="index")
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
from typing_extensions import deprecated
|
|
4
|
+
|
|
5
|
+
from uipath.tracing._traced import traced
|
|
6
|
+
|
|
7
|
+
from .._config import Config
|
|
8
|
+
from .._execution_context import ExecutionContext
|
|
9
|
+
from .._utils import Endpoint, RequestSpec
|
|
10
|
+
from ._base_service import BaseService
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class FolderService(BaseService):
|
|
14
|
+
"""Service for managing UiPath Folders.
|
|
15
|
+
|
|
16
|
+
A folder represents a single area for data organization
|
|
17
|
+
and access control - it is created when you need to categorize, manage, and enforce authorization rules for a group
|
|
18
|
+
of UiPath resources (i.e. processes, assets, connections, storage buckets etc.) or other folders
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
def __init__(self, config: Config, execution_context: ExecutionContext) -> None:
|
|
22
|
+
super().__init__(config=config, execution_context=execution_context)
|
|
23
|
+
|
|
24
|
+
@traced(name="folder_retrieve_key_by_folder_path", run_type="uipath")
|
|
25
|
+
@deprecated("Use retrieve_key instead")
|
|
26
|
+
def retrieve_key_by_folder_path(self, folder_path: str) -> Optional[str]:
|
|
27
|
+
return self.retrieve_key(folder_path=folder_path)
|
|
28
|
+
|
|
29
|
+
@traced(name="folder_retrieve_key", run_type="uipath")
|
|
30
|
+
def retrieve_key(self, *, folder_path: str) -> Optional[str]:
|
|
31
|
+
"""Retrieve the folder key by folder path with pagination support.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
folder_path: The fully qualified folder path to search for.
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
The folder key if found, None otherwise.
|
|
38
|
+
"""
|
|
39
|
+
skip = 0
|
|
40
|
+
take = 20
|
|
41
|
+
|
|
42
|
+
while True:
|
|
43
|
+
spec = self._retrieve_spec(folder_path, skip=skip, take=take)
|
|
44
|
+
response = self.request(
|
|
45
|
+
spec.method,
|
|
46
|
+
url=spec.endpoint,
|
|
47
|
+
params=spec.params,
|
|
48
|
+
).json()
|
|
49
|
+
|
|
50
|
+
# Search for the folder in current page
|
|
51
|
+
folder_key = next(
|
|
52
|
+
(
|
|
53
|
+
item["Key"]
|
|
54
|
+
for item in response["PageItems"]
|
|
55
|
+
if item["FullyQualifiedName"] == folder_path
|
|
56
|
+
),
|
|
57
|
+
None,
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
if folder_key is not None:
|
|
61
|
+
return folder_key
|
|
62
|
+
|
|
63
|
+
page_items = response["PageItems"]
|
|
64
|
+
if len(page_items) < take:
|
|
65
|
+
break
|
|
66
|
+
|
|
67
|
+
skip += take
|
|
68
|
+
|
|
69
|
+
return None
|
|
70
|
+
|
|
71
|
+
def _retrieve_spec(
|
|
72
|
+
self, folder_path: str, *, skip: int = 0, take: int = 20
|
|
73
|
+
) -> RequestSpec:
|
|
74
|
+
folder_name = folder_path.split("/")[-1]
|
|
75
|
+
return RequestSpec(
|
|
76
|
+
method="GET",
|
|
77
|
+
endpoint=Endpoint(
|
|
78
|
+
"orchestrator_/api/FoldersNavigation/GetFoldersForCurrentUser"
|
|
79
|
+
),
|
|
80
|
+
params={
|
|
81
|
+
"searchText": folder_name,
|
|
82
|
+
"skip": skip,
|
|
83
|
+
"take": take,
|
|
84
|
+
},
|
|
85
|
+
)
|
|
@@ -38,12 +38,13 @@ class TestContextGroundingService:
|
|
|
38
38
|
version: str,
|
|
39
39
|
) -> None:
|
|
40
40
|
httpx_mock.add_response(
|
|
41
|
-
url=f"{base_url}{org}{tenant}/orchestrator_/
|
|
41
|
+
url=f"{base_url}{org}{tenant}/orchestrator_/api/FoldersNavigation/GetFoldersForCurrentUser?searchText=test-folder-path&skip=0&take=20",
|
|
42
42
|
status_code=200,
|
|
43
43
|
json={
|
|
44
|
-
"
|
|
44
|
+
"PageItems": [
|
|
45
45
|
{
|
|
46
46
|
"Key": "test-folder-key",
|
|
47
|
+
"FullyQualifiedName": "test-folder-path",
|
|
47
48
|
}
|
|
48
49
|
]
|
|
49
50
|
},
|
|
@@ -67,12 +68,13 @@ class TestContextGroundingService:
|
|
|
67
68
|
)
|
|
68
69
|
|
|
69
70
|
httpx_mock.add_response(
|
|
70
|
-
url=f"{base_url}{org}{tenant}/orchestrator_/
|
|
71
|
+
url=f"{base_url}{org}{tenant}/orchestrator_/api/FoldersNavigation/GetFoldersForCurrentUser?searchText=test-folder-path&skip=0&take=20",
|
|
71
72
|
status_code=200,
|
|
72
73
|
json={
|
|
73
|
-
"
|
|
74
|
+
"PageItems": [
|
|
74
75
|
{
|
|
75
76
|
"Key": "test-folder-key",
|
|
77
|
+
"FullyQualifiedName": "test-folder-path",
|
|
76
78
|
}
|
|
77
79
|
]
|
|
78
80
|
},
|
|
@@ -130,12 +132,13 @@ class TestContextGroundingService:
|
|
|
130
132
|
version: str,
|
|
131
133
|
) -> None:
|
|
132
134
|
httpx_mock.add_response(
|
|
133
|
-
url=f"{base_url}{org}{tenant}/orchestrator_/
|
|
135
|
+
url=f"{base_url}{org}{tenant}/orchestrator_/api/FoldersNavigation/GetFoldersForCurrentUser?searchText=test-folder-path&skip=0&take=20",
|
|
134
136
|
status_code=200,
|
|
135
137
|
json={
|
|
136
|
-
"
|
|
138
|
+
"PageItems": [
|
|
137
139
|
{
|
|
138
140
|
"Key": "test-folder-key",
|
|
141
|
+
"FullyQualifiedName": "test-folder-path",
|
|
139
142
|
}
|
|
140
143
|
]
|
|
141
144
|
},
|
|
@@ -159,12 +162,13 @@ class TestContextGroundingService:
|
|
|
159
162
|
)
|
|
160
163
|
|
|
161
164
|
httpx_mock.add_response(
|
|
162
|
-
url=f"{base_url}{org}{tenant}/orchestrator_/
|
|
165
|
+
url=f"{base_url}{org}{tenant}/orchestrator_/api/FoldersNavigation/GetFoldersForCurrentUser?searchText=test-folder-path&skip=0&take=20",
|
|
163
166
|
status_code=200,
|
|
164
167
|
json={
|
|
165
|
-
"
|
|
168
|
+
"PageItems": [
|
|
166
169
|
{
|
|
167
170
|
"Key": "test-folder-key",
|
|
171
|
+
"FullyQualifiedName": "test-folder-path",
|
|
168
172
|
}
|
|
169
173
|
]
|
|
170
174
|
},
|
|
@@ -221,12 +225,13 @@ class TestContextGroundingService:
|
|
|
221
225
|
version: str,
|
|
222
226
|
) -> None:
|
|
223
227
|
httpx_mock.add_response(
|
|
224
|
-
url=f"{base_url}{org}{tenant}/orchestrator_/
|
|
228
|
+
url=f"{base_url}{org}{tenant}/orchestrator_/api/FoldersNavigation/GetFoldersForCurrentUser?searchText=test-folder-path&skip=0&take=20",
|
|
225
229
|
status_code=200,
|
|
226
230
|
json={
|
|
227
|
-
"
|
|
231
|
+
"PageItems": [
|
|
228
232
|
{
|
|
229
233
|
"Key": "test-folder-key",
|
|
234
|
+
"FullyQualifiedName": "test-folder-path",
|
|
230
235
|
}
|
|
231
236
|
]
|
|
232
237
|
},
|
|
@@ -280,17 +285,17 @@ class TestContextGroundingService:
|
|
|
280
285
|
version: str,
|
|
281
286
|
) -> None:
|
|
282
287
|
httpx_mock.add_response(
|
|
283
|
-
url=f"{base_url}{org}{tenant}/orchestrator_/
|
|
288
|
+
url=f"{base_url}{org}{tenant}/orchestrator_/api/FoldersNavigation/GetFoldersForCurrentUser?searchText=test-folder-path&skip=0&take=20",
|
|
284
289
|
status_code=200,
|
|
285
290
|
json={
|
|
286
|
-
"
|
|
291
|
+
"PageItems": [
|
|
287
292
|
{
|
|
288
293
|
"Key": "test-folder-key",
|
|
294
|
+
"FullyQualifiedName": "test-folder-path",
|
|
289
295
|
}
|
|
290
296
|
]
|
|
291
297
|
},
|
|
292
298
|
)
|
|
293
|
-
|
|
294
299
|
httpx_mock.add_response(
|
|
295
300
|
url=f"{base_url}{org}{tenant}/ecs_/v2/indexes?$filter=Name eq 'test-index'&$expand=dataSource",
|
|
296
301
|
status_code=200,
|
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
from pytest_httpx import HTTPXMock
|
|
3
|
+
|
|
4
|
+
from uipath._config import Config
|
|
5
|
+
from uipath._execution_context import ExecutionContext
|
|
6
|
+
from uipath._services.folder_service import FolderService
|
|
7
|
+
from uipath._utils.constants import HEADER_USER_AGENT
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@pytest.fixture
|
|
11
|
+
def service(
|
|
12
|
+
config: Config,
|
|
13
|
+
execution_context: ExecutionContext,
|
|
14
|
+
monkeypatch: pytest.MonkeyPatch,
|
|
15
|
+
) -> FolderService:
|
|
16
|
+
monkeypatch.setenv("UIPATH_FOLDER_PATH", "test-folder-path")
|
|
17
|
+
return FolderService(config=config, execution_context=execution_context)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class TestFolderService:
|
|
21
|
+
def test_retrieve_key_by_folder_path(
|
|
22
|
+
self,
|
|
23
|
+
httpx_mock: HTTPXMock,
|
|
24
|
+
service: FolderService,
|
|
25
|
+
base_url: str,
|
|
26
|
+
org: str,
|
|
27
|
+
tenant: str,
|
|
28
|
+
version: str,
|
|
29
|
+
) -> None:
|
|
30
|
+
httpx_mock.add_response(
|
|
31
|
+
url=f"{base_url}{org}{tenant}/orchestrator_/api/FoldersNavigation/GetFoldersForCurrentUser?searchText=test-folder-path&skip=0&take=20",
|
|
32
|
+
status_code=200,
|
|
33
|
+
json={
|
|
34
|
+
"PageItems": [
|
|
35
|
+
{
|
|
36
|
+
"Key": "test-folder-key",
|
|
37
|
+
"FullyQualifiedName": "test-folder-path",
|
|
38
|
+
}
|
|
39
|
+
]
|
|
40
|
+
},
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
with pytest.warns(DeprecationWarning, match="Use retrieve_key instead"):
|
|
44
|
+
folder_key = service.retrieve_key_by_folder_path("test-folder-path")
|
|
45
|
+
|
|
46
|
+
assert folder_key == "test-folder-key"
|
|
47
|
+
|
|
48
|
+
sent_request = httpx_mock.get_request()
|
|
49
|
+
if sent_request is None:
|
|
50
|
+
raise Exception("No request was sent")
|
|
51
|
+
|
|
52
|
+
assert sent_request.method == "GET"
|
|
53
|
+
assert (
|
|
54
|
+
sent_request.url
|
|
55
|
+
== f"{base_url}{org}{tenant}/orchestrator_/api/FoldersNavigation/GetFoldersForCurrentUser?searchText=test-folder-path&skip=0&take=20"
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
assert HEADER_USER_AGENT in sent_request.headers
|
|
59
|
+
assert (
|
|
60
|
+
sent_request.headers[HEADER_USER_AGENT]
|
|
61
|
+
== f"UiPath.Python.Sdk/UiPath.Python.Sdk.Activities.FolderService.retrieve_key/{version}"
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
def test_retrieve_key_by_folder_path_not_found(
|
|
65
|
+
self,
|
|
66
|
+
httpx_mock: HTTPXMock,
|
|
67
|
+
service: FolderService,
|
|
68
|
+
base_url: str,
|
|
69
|
+
org: str,
|
|
70
|
+
tenant: str,
|
|
71
|
+
version: str,
|
|
72
|
+
) -> None:
|
|
73
|
+
httpx_mock.add_response(
|
|
74
|
+
url=f"{base_url}{org}{tenant}/orchestrator_/api/FoldersNavigation/GetFoldersForCurrentUser?searchText=non-existent-folder&skip=0&take=20",
|
|
75
|
+
status_code=200,
|
|
76
|
+
json={"PageItems": []},
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
with pytest.warns(DeprecationWarning, match="Use retrieve_key instead"):
|
|
80
|
+
folder_key = service.retrieve_key_by_folder_path("non-existent-folder")
|
|
81
|
+
|
|
82
|
+
assert folder_key is None
|
|
83
|
+
|
|
84
|
+
sent_request = httpx_mock.get_request()
|
|
85
|
+
if sent_request is None:
|
|
86
|
+
raise Exception("No request was sent")
|
|
87
|
+
|
|
88
|
+
assert sent_request.method == "GET"
|
|
89
|
+
assert (
|
|
90
|
+
sent_request.url
|
|
91
|
+
== f"{base_url}{org}{tenant}/orchestrator_/api/FoldersNavigation/GetFoldersForCurrentUser?searchText=non-existent-folder&skip=0&take=20"
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
assert HEADER_USER_AGENT in sent_request.headers
|
|
95
|
+
assert (
|
|
96
|
+
sent_request.headers[HEADER_USER_AGENT]
|
|
97
|
+
== f"UiPath.Python.Sdk/UiPath.Python.Sdk.Activities.FolderService.retrieve_key/{version}"
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
def test_retrieve_key(
|
|
101
|
+
self,
|
|
102
|
+
httpx_mock: HTTPXMock,
|
|
103
|
+
service: FolderService,
|
|
104
|
+
base_url: str,
|
|
105
|
+
org: str,
|
|
106
|
+
tenant: str,
|
|
107
|
+
version: str,
|
|
108
|
+
) -> None:
|
|
109
|
+
httpx_mock.add_response(
|
|
110
|
+
url=f"{base_url}{org}{tenant}/orchestrator_/api/FoldersNavigation/GetFoldersForCurrentUser?searchText=test-folder-path&skip=0&take=20",
|
|
111
|
+
status_code=200,
|
|
112
|
+
json={
|
|
113
|
+
"PageItems": [
|
|
114
|
+
{
|
|
115
|
+
"Key": "test-folder-key",
|
|
116
|
+
"FullyQualifiedName": "test-folder-path",
|
|
117
|
+
}
|
|
118
|
+
]
|
|
119
|
+
},
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
folder_key = service.retrieve_key(folder_path="test-folder-path")
|
|
123
|
+
|
|
124
|
+
assert folder_key == "test-folder-key"
|
|
125
|
+
|
|
126
|
+
sent_request = httpx_mock.get_request()
|
|
127
|
+
if sent_request is None:
|
|
128
|
+
raise Exception("No request was sent")
|
|
129
|
+
|
|
130
|
+
assert sent_request.method == "GET"
|
|
131
|
+
assert (
|
|
132
|
+
sent_request.url
|
|
133
|
+
== f"{base_url}{org}{tenant}/orchestrator_/api/FoldersNavigation/GetFoldersForCurrentUser?searchText=test-folder-path&skip=0&take=20"
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
assert HEADER_USER_AGENT in sent_request.headers
|
|
137
|
+
assert (
|
|
138
|
+
sent_request.headers[HEADER_USER_AGENT]
|
|
139
|
+
== f"UiPath.Python.Sdk/UiPath.Python.Sdk.Activities.FolderService.retrieve_key/{version}"
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
def test_retrieve_key_not_found(
|
|
143
|
+
self,
|
|
144
|
+
httpx_mock: HTTPXMock,
|
|
145
|
+
service: FolderService,
|
|
146
|
+
base_url: str,
|
|
147
|
+
org: str,
|
|
148
|
+
tenant: str,
|
|
149
|
+
version: str,
|
|
150
|
+
) -> None:
|
|
151
|
+
httpx_mock.add_response(
|
|
152
|
+
url=f"{base_url}{org}{tenant}/orchestrator_/api/FoldersNavigation/GetFoldersForCurrentUser?searchText=non-existent-folder&skip=0&take=20",
|
|
153
|
+
status_code=200,
|
|
154
|
+
json={"PageItems": []},
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
folder_key = service.retrieve_key(folder_path="non-existent-folder")
|
|
158
|
+
|
|
159
|
+
assert folder_key is None
|
|
160
|
+
|
|
161
|
+
sent_request = httpx_mock.get_request()
|
|
162
|
+
if sent_request is None:
|
|
163
|
+
raise Exception("No request was sent")
|
|
164
|
+
|
|
165
|
+
assert sent_request.method == "GET"
|
|
166
|
+
assert (
|
|
167
|
+
sent_request.url
|
|
168
|
+
== f"{base_url}{org}{tenant}/orchestrator_/api/FoldersNavigation/GetFoldersForCurrentUser?searchText=non-existent-folder&skip=0&take=20"
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
assert HEADER_USER_AGENT in sent_request.headers
|
|
172
|
+
assert (
|
|
173
|
+
sent_request.headers[HEADER_USER_AGENT]
|
|
174
|
+
== f"UiPath.Python.Sdk/UiPath.Python.Sdk.Activities.FolderService.retrieve_key/{version}"
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
def test_retrieve_key_found_on_second_page(
|
|
178
|
+
self,
|
|
179
|
+
httpx_mock: HTTPXMock,
|
|
180
|
+
service: FolderService,
|
|
181
|
+
base_url: str,
|
|
182
|
+
org: str,
|
|
183
|
+
tenant: str,
|
|
184
|
+
version: str,
|
|
185
|
+
) -> None:
|
|
186
|
+
"""Test that retrieve_key can find a folder on subsequent pages through pagination."""
|
|
187
|
+
# First page - folder not found
|
|
188
|
+
httpx_mock.add_response(
|
|
189
|
+
url=f"{base_url}{org}{tenant}/orchestrator_/api/FoldersNavigation/GetFoldersForCurrentUser?searchText=target-folder&skip=0&take=20",
|
|
190
|
+
status_code=200,
|
|
191
|
+
json={
|
|
192
|
+
"PageItems": [
|
|
193
|
+
{
|
|
194
|
+
"Key": f"folder-key-{i}",
|
|
195
|
+
"FullyQualifiedName": f"other-folder-{i}",
|
|
196
|
+
}
|
|
197
|
+
for i in range(20) # Full page of 20 items, none matching
|
|
198
|
+
]
|
|
199
|
+
},
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
# Second page - folder found
|
|
203
|
+
httpx_mock.add_response(
|
|
204
|
+
url=f"{base_url}{org}{tenant}/orchestrator_/api/FoldersNavigation/GetFoldersForCurrentUser?searchText=target-folder&skip=20&take=20",
|
|
205
|
+
status_code=200,
|
|
206
|
+
json={
|
|
207
|
+
"PageItems": [
|
|
208
|
+
{
|
|
209
|
+
"Key": "target-folder-key",
|
|
210
|
+
"FullyQualifiedName": "target-folder",
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
"Key": "another-folder-key",
|
|
214
|
+
"FullyQualifiedName": "another-folder",
|
|
215
|
+
},
|
|
216
|
+
]
|
|
217
|
+
},
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
folder_key = service.retrieve_key(folder_path="target-folder")
|
|
221
|
+
|
|
222
|
+
assert folder_key == "target-folder-key"
|
|
223
|
+
|
|
224
|
+
requests = httpx_mock.get_requests()
|
|
225
|
+
assert len(requests) == 2
|
|
226
|
+
|
|
227
|
+
assert requests[0].method == "GET"
|
|
228
|
+
assert (
|
|
229
|
+
requests[0].url
|
|
230
|
+
== f"{base_url}{org}{tenant}/orchestrator_/api/FoldersNavigation/GetFoldersForCurrentUser?searchText=target-folder&skip=0&take=20"
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
assert requests[1].method == "GET"
|
|
234
|
+
assert (
|
|
235
|
+
requests[1].url
|
|
236
|
+
== f"{base_url}{org}{tenant}/orchestrator_/api/FoldersNavigation/GetFoldersForCurrentUser?searchText=target-folder&skip=20&take=20"
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
def test_retrieve_key_not_found_after_pagination(
|
|
240
|
+
self,
|
|
241
|
+
httpx_mock: HTTPXMock,
|
|
242
|
+
service: FolderService,
|
|
243
|
+
base_url: str,
|
|
244
|
+
org: str,
|
|
245
|
+
tenant: str,
|
|
246
|
+
version: str,
|
|
247
|
+
) -> None:
|
|
248
|
+
"""Test that retrieve_key returns None when folder is not found after paginating through all results."""
|
|
249
|
+
# First page - full page, no match
|
|
250
|
+
httpx_mock.add_response(
|
|
251
|
+
url=f"{base_url}{org}{tenant}/orchestrator_/api/FoldersNavigation/GetFoldersForCurrentUser?searchText=missing-folder&skip=0&take=20",
|
|
252
|
+
status_code=200,
|
|
253
|
+
json={
|
|
254
|
+
"PageItems": [
|
|
255
|
+
{
|
|
256
|
+
"Key": f"folder-key-{i}",
|
|
257
|
+
"FullyQualifiedName": f"other-folder-{i}",
|
|
258
|
+
}
|
|
259
|
+
for i in range(20) # Full page of 20 items
|
|
260
|
+
]
|
|
261
|
+
},
|
|
262
|
+
)
|
|
263
|
+
|
|
264
|
+
# Second page - no match
|
|
265
|
+
httpx_mock.add_response(
|
|
266
|
+
url=f"{base_url}{org}{tenant}/orchestrator_/api/FoldersNavigation/GetFoldersForCurrentUser?searchText=missing-folder&skip=20&take=20",
|
|
267
|
+
status_code=200,
|
|
268
|
+
json={
|
|
269
|
+
"PageItems": [
|
|
270
|
+
{
|
|
271
|
+
"Key": "final-folder-key",
|
|
272
|
+
"FullyQualifiedName": "final-folder",
|
|
273
|
+
},
|
|
274
|
+
]
|
|
275
|
+
},
|
|
276
|
+
)
|
|
277
|
+
|
|
278
|
+
folder_key = service.retrieve_key(folder_path="missing-folder")
|
|
279
|
+
|
|
280
|
+
assert folder_key is None
|
|
281
|
+
|
|
282
|
+
requests = httpx_mock.get_requests()
|
|
283
|
+
assert len(requests) == 2
|
|
284
|
+
|
|
285
|
+
assert requests[0].method == "GET"
|
|
286
|
+
assert (
|
|
287
|
+
requests[0].url
|
|
288
|
+
== f"{base_url}{org}{tenant}/orchestrator_/api/FoldersNavigation/GetFoldersForCurrentUser?searchText=missing-folder&skip=0&take=20"
|
|
289
|
+
)
|
|
290
|
+
|
|
291
|
+
assert requests[1].method == "GET"
|
|
292
|
+
assert (
|
|
293
|
+
requests[1].url
|
|
294
|
+
== f"{base_url}{org}{tenant}/orchestrator_/api/FoldersNavigation/GetFoldersForCurrentUser?searchText=missing-folder&skip=20&take=20"
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
def test_retrieve_key_found_on_third_page(
|
|
298
|
+
self,
|
|
299
|
+
httpx_mock: HTTPXMock,
|
|
300
|
+
service: FolderService,
|
|
301
|
+
base_url: str,
|
|
302
|
+
org: str,
|
|
303
|
+
tenant: str,
|
|
304
|
+
version: str,
|
|
305
|
+
) -> None:
|
|
306
|
+
"""Test that retrieve_key can find a folder on the third page through multiple pagination requests."""
|
|
307
|
+
# First page
|
|
308
|
+
httpx_mock.add_response(
|
|
309
|
+
url=f"{base_url}{org}{tenant}/orchestrator_/api/FoldersNavigation/GetFoldersForCurrentUser?searchText=deep-folder&skip=0&take=20",
|
|
310
|
+
status_code=200,
|
|
311
|
+
json={
|
|
312
|
+
"PageItems": [
|
|
313
|
+
{
|
|
314
|
+
"Key": f"folder-key-{i}",
|
|
315
|
+
"FullyQualifiedName": f"page1-folder-{i}",
|
|
316
|
+
}
|
|
317
|
+
for i in range(20)
|
|
318
|
+
]
|
|
319
|
+
},
|
|
320
|
+
)
|
|
321
|
+
|
|
322
|
+
# Second page
|
|
323
|
+
httpx_mock.add_response(
|
|
324
|
+
url=f"{base_url}{org}{tenant}/orchestrator_/api/FoldersNavigation/GetFoldersForCurrentUser?searchText=deep-folder&skip=20&take=20",
|
|
325
|
+
status_code=200,
|
|
326
|
+
json={
|
|
327
|
+
"PageItems": [
|
|
328
|
+
{
|
|
329
|
+
"Key": f"folder-key-{i}",
|
|
330
|
+
"FullyQualifiedName": f"page2-folder-{i}",
|
|
331
|
+
}
|
|
332
|
+
for i in range(20)
|
|
333
|
+
]
|
|
334
|
+
},
|
|
335
|
+
)
|
|
336
|
+
|
|
337
|
+
# Third page - folder found
|
|
338
|
+
httpx_mock.add_response(
|
|
339
|
+
url=f"{base_url}{org}{tenant}/orchestrator_/api/FoldersNavigation/GetFoldersForCurrentUser?searchText=deep-folder&skip=40&take=20",
|
|
340
|
+
status_code=200,
|
|
341
|
+
json={
|
|
342
|
+
"PageItems": [
|
|
343
|
+
{
|
|
344
|
+
"Key": "some-other-key",
|
|
345
|
+
"FullyQualifiedName": "some-other-folder",
|
|
346
|
+
},
|
|
347
|
+
{
|
|
348
|
+
"Key": "deep-folder-key",
|
|
349
|
+
"FullyQualifiedName": "deep-folder",
|
|
350
|
+
},
|
|
351
|
+
]
|
|
352
|
+
},
|
|
353
|
+
)
|
|
354
|
+
|
|
355
|
+
folder_key = service.retrieve_key(folder_path="deep-folder")
|
|
356
|
+
|
|
357
|
+
assert folder_key == "deep-folder-key"
|
|
358
|
+
|
|
359
|
+
requests = httpx_mock.get_requests()
|
|
360
|
+
assert len(requests) == 3
|
|
361
|
+
|
|
362
|
+
expected_urls = [
|
|
363
|
+
f"{base_url}{org}{tenant}/orchestrator_/api/FoldersNavigation/GetFoldersForCurrentUser?searchText=deep-folder&skip=0&take=20",
|
|
364
|
+
f"{base_url}{org}{tenant}/orchestrator_/api/FoldersNavigation/GetFoldersForCurrentUser?searchText=deep-folder&skip=20&take=20",
|
|
365
|
+
f"{base_url}{org}{tenant}/orchestrator_/api/FoldersNavigation/GetFoldersForCurrentUser?searchText=deep-folder&skip=40&take=20",
|
|
366
|
+
]
|
|
367
|
+
|
|
368
|
+
for i, request in enumerate(requests):
|
|
369
|
+
assert request.method == "GET"
|
|
370
|
+
assert request.url == expected_urls[i]
|