uipath 2.0.66__tar.gz → 2.0.68__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.66 → uipath-2.0.68}/PKG-INFO +1 -1
- {uipath-2.0.66 → uipath-2.0.68}/docs/cli/index.md +36 -3
- {uipath-2.0.66 → uipath-2.0.68}/pyproject.toml +1 -1
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_services/context_grounding_service.py +4 -2
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_services/folder_service.py +44 -17
- {uipath-2.0.66 → uipath-2.0.68}/tests/sdk/services/test_context_grounding_service.py +6 -7
- uipath-2.0.68/tests/sdk/services/test_folder_service.py +370 -0
- {uipath-2.0.66 → uipath-2.0.68}/uv.lock +1 -1
- uipath-2.0.66/tests/sdk/services/test_folder_service.py +0 -175
- {uipath-2.0.66 → uipath-2.0.68}/.cursorrules +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/.editorconfig +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/.gitattributes +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/.github/workflows/cd.yml +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/.github/workflows/ci.yml +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/.github/workflows/commitlint.yml +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/.github/workflows/lint.yml +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/.github/workflows/publish-dev.yml +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/.github/workflows/publish-docs.yml +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/.github/workflows/slack.yml +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/.github/workflows/test.yml +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/.gitignore +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/.pre-commit-config.yaml +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/.python-version +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/.vscode/extensions.json +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/.vscode/launch.json +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/.vscode/settings.json +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/CONTRIBUTING.md +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/LICENSE +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/README.md +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/docs/CONTRIBUTING.md +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/docs/FAQ.md +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/docs/assets/env-preparation-failed-dark.png +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/docs/assets/env-preparation-failed-light.png +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/docs/assets/favicon.png +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/docs/assets/logo-dark.svg +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/docs/assets/logo-light.svg +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/docs/core/actions.md +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/docs/core/assets/cloud_env_var_dark.gif +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/docs/core/assets/cloud_env_var_light.gif +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/docs/core/assets/cloud_env_var_secret_dark.png +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/docs/core/assets/cloud_env_var_secret_light.png +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/docs/core/assets/copy_path_dark.png +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/docs/core/assets/copy_path_light.png +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/docs/core/assets.md +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/docs/core/attachments.md +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/docs/core/buckets.md +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/docs/core/connections.md +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/docs/core/context_grounding.md +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/docs/core/environment_variables.md +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/docs/core/getting_started.md +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/docs/core/jobs.md +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/docs/core/processes.md +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/docs/core/queues.md +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/docs/core/traced.md +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/docs/hooks.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/docs/javascripts/extra.js +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/docs/langchain/chat_models.md +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/docs/langchain/context_grounding.md +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/docs/langchain/human_in_the_loop.md +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/docs/overrides/main.html +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/docs/overrides/partials/actions.html +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/docs/overrides/partials/logo.html +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/docs/release_policy.md +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/docs/stylesheets/extra.css +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/justfile +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/mkdocs.yml +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/py.typed +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/__init__.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_cli/README.md +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_cli/__init__.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_cli/_auth/_auth_server.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_cli/_auth/_models.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_cli/_auth/_oidc_utils.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_cli/_auth/_portal_service.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_cli/_auth/_utils.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_cli/_auth/auth_config.json +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_cli/_auth/index.html +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_cli/_auth/localhost.crt +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_cli/_auth/localhost.key +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_cli/_runtime/_contracts.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_cli/_runtime/_escalation.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_cli/_runtime/_hitl.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_cli/_runtime/_logging.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_cli/_runtime/_runtime.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_cli/_templates/.psmdcp.template +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_cli/_templates/.rels.template +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_cli/_templates/[Content_Types].xml.template +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_cli/_templates/main.py.template +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_cli/_templates/package.nuspec.template +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_cli/_utils/_common.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_cli/_utils/_console.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_cli/_utils/_constants.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_cli/_utils/_debug.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_cli/_utils/_folders.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_cli/_utils/_input_args.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_cli/_utils/_parse_ast.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_cli/_utils/_processes.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_cli/_utils/_tracing.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_cli/cli_auth.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_cli/cli_deploy.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_cli/cli_init.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_cli/cli_invoke.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_cli/cli_new.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_cli/cli_pack.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_cli/cli_publish.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_cli/cli_run.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_cli/middlewares.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_cli/spinner.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_config.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_execution_context.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_folder_context.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_services/__init__.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_services/_base_service.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_services/actions_service.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_services/api_client.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_services/assets_service.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_services/attachments_service.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_services/buckets_service.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_services/connections_service.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_services/jobs_service.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_services/llm_gateway_service.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_services/processes_service.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_services/queues_service.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_uipath.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_utils/__init__.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_utils/_endpoint.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_utils/_infer_bindings.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_utils/_logs.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_utils/_read_overwrites.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_utils/_request_override.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_utils/_request_spec.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_utils/_url.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_utils/_user_agent.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/_utils/constants.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/models/__init__.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/models/action_schema.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/models/actions.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/models/assets.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/models/attachment.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/models/buckets.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/models/connections.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/models/context_grounding.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/models/context_grounding_index.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/models/errors.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/models/exceptions.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/models/interrupt_models.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/models/job.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/models/llm_gateway.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/models/processes.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/models/queues.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/py.typed +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/telemetry/__init__.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/telemetry/_constants.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/telemetry/_track.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/tracing/__init__.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/tracing/_otel_exporters.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/tracing/_traced.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/src/uipath/tracing/_utils.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/tests/__init__.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/tests/cli/conftest.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/tests/cli/mocks/bindings_script.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/tests/cli/mocks/pyproject.toml +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/tests/cli/mocks/simple_script.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/tests/cli/mocks/uipath-mock.json +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/tests/cli/mocks/uipath-simple-script-mock.json +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/tests/cli/test_hitl.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/tests/cli/test_init.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/tests/cli/test_invoke.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/tests/cli/test_new.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/tests/cli/test_pack.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/tests/cli/test_publish.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/tests/cli/test_run.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/tests/cli/test_utils.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/tests/cli/utils/project_details.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/tests/cli/utils/uipath_json.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/tests/conftest.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/tests/sdk/services/conftest.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/tests/sdk/services/test_actions_service.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/tests/sdk/services/test_api_client.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/tests/sdk/services/test_assets_service.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/tests/sdk/services/test_attachments_service.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/tests/sdk/services/test_base_service.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/tests/sdk/services/test_buckets_service.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/tests/sdk/services/test_connections_service.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/tests/sdk/services/test_jobs_service.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/tests/sdk/services/test_llm_integration.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/tests/sdk/services/test_llm_service.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/tests/sdk/services/test_processes_service.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/tests/sdk/services/test_queues_service.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/tests/sdk/services/test_uipath_llm_integration.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/tests/sdk/test_bindings_inference.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/tests/sdk/test_config.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/tests/sdk/test_overwrites.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/tests/tracing/test_otel_exporters.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/tests/tracing/test_span_utils.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/tests/tracing/test_traced.py +0 -0
- {uipath-2.0.66 → uipath-2.0.68}/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.68
|
|
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
|
|
@@ -54,9 +54,10 @@ For step-by-step debugging with breakpoints and variable inspection (supported f
|
|
|
54
54
|
# Run agent with debugging enabled
|
|
55
55
|
uipath run [ENTRYPOINT] [INPUT] --debug
|
|
56
56
|
```
|
|
57
|
-
For vscode:
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
For vscode:
|
|
58
|
+
1. add the [debug configuration](https://github.com/UiPath/uipath-python/blob/main/.vscode/launch.json) in your `.vscode/launch.json` file.
|
|
59
|
+
2. Place breakpoints in your code where needed.
|
|
60
|
+
3. Use the shortcut `F5`, or navigate to Run -> Start Debugging -> Python Debugger: Attach.
|
|
60
61
|
|
|
61
62
|
Upon starting the debugging process, one should see the following logs in terminal:
|
|
62
63
|
```console
|
|
@@ -106,6 +107,38 @@ uipath run agent '{\"topic\":\"uipath\"}'
|
|
|
106
107
|
|
|
107
108
|
Packages your project into a `.nupkg` file that can be deployed to UiPath.
|
|
108
109
|
|
|
110
|
+
/// info
|
|
111
|
+
### Default Files Included in `.nupkg`
|
|
112
|
+
|
|
113
|
+
By default, the following file types are included in the `.nupkg` file:
|
|
114
|
+
|
|
115
|
+
- `.py`
|
|
116
|
+
- `.mermaid`
|
|
117
|
+
- `.json`
|
|
118
|
+
- `.yaml`
|
|
119
|
+
- `.yml`
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
### Including Extra Files
|
|
124
|
+
|
|
125
|
+
To include additional files, update the `uipath.json` file by adding a `settings` section. Use the following configuration format:
|
|
126
|
+
|
|
127
|
+
```json
|
|
128
|
+
{
|
|
129
|
+
"settings": {
|
|
130
|
+
"filesIncluded": [
|
|
131
|
+
"<file here>"
|
|
132
|
+
],
|
|
133
|
+
"fileExtensionsIncluded": [
|
|
134
|
+
"<new file extension to include (e.g., 'go')>"
|
|
135
|
+
]
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
///
|
|
141
|
+
|
|
109
142
|
/// warning
|
|
110
143
|
Your `pyproject.toml` must include:
|
|
111
144
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "uipath"
|
|
3
|
-
version = "2.0.
|
|
3
|
+
version = "2.0.68"
|
|
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"
|
|
@@ -673,7 +673,7 @@ class ContextGroundingService(FolderContext, BaseService):
|
|
|
673
673
|
)
|
|
674
674
|
|
|
675
675
|
if folder_key is None:
|
|
676
|
-
raise ValueError("
|
|
676
|
+
raise ValueError("ContextGrounding: Failed to resolve folder key")
|
|
677
677
|
|
|
678
678
|
return folder_key
|
|
679
679
|
|
|
@@ -681,4 +681,6 @@ class ContextGroundingService(FolderContext, BaseService):
|
|
|
681
681
|
try:
|
|
682
682
|
return index.data_source.bucketName, index.data_source.folder # type: ignore
|
|
683
683
|
except AttributeError as e:
|
|
684
|
-
raise Exception(
|
|
684
|
+
raise Exception(
|
|
685
|
+
"ContextGrounding: Cannot extract bucket data from index"
|
|
686
|
+
) from e
|
|
@@ -28,23 +28,49 @@ class FolderService(BaseService):
|
|
|
28
28
|
|
|
29
29
|
@traced(name="folder_retrieve_key", run_type="uipath")
|
|
30
30
|
def retrieve_key(self, *, folder_path: str) -> Optional[str]:
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
)
|
|
44
|
-
|
|
45
|
-
|
|
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
|
|
46
70
|
|
|
47
|
-
def _retrieve_spec(
|
|
71
|
+
def _retrieve_spec(
|
|
72
|
+
self, folder_path: str, *, skip: int = 0, take: int = 20
|
|
73
|
+
) -> RequestSpec:
|
|
48
74
|
folder_name = folder_path.split("/")[-1]
|
|
49
75
|
return RequestSpec(
|
|
50
76
|
method="GET",
|
|
@@ -53,6 +79,7 @@ class FolderService(BaseService):
|
|
|
53
79
|
),
|
|
54
80
|
params={
|
|
55
81
|
"searchText": folder_name,
|
|
56
|
-
"
|
|
82
|
+
"skip": skip,
|
|
83
|
+
"take": take,
|
|
57
84
|
},
|
|
58
85
|
)
|
|
@@ -38,7 +38,7 @@ class TestContextGroundingService:
|
|
|
38
38
|
version: str,
|
|
39
39
|
) -> None:
|
|
40
40
|
httpx_mock.add_response(
|
|
41
|
-
url=f"{base_url}{org}{tenant}/orchestrator_/api/FoldersNavigation/GetFoldersForCurrentUser?searchText=test-folder-path&take=
|
|
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": [
|
|
@@ -68,7 +68,7 @@ class TestContextGroundingService:
|
|
|
68
68
|
)
|
|
69
69
|
|
|
70
70
|
httpx_mock.add_response(
|
|
71
|
-
url=f"{base_url}{org}{tenant}/orchestrator_/api/FoldersNavigation/GetFoldersForCurrentUser?searchText=test-folder-path&take=
|
|
71
|
+
url=f"{base_url}{org}{tenant}/orchestrator_/api/FoldersNavigation/GetFoldersForCurrentUser?searchText=test-folder-path&skip=0&take=20",
|
|
72
72
|
status_code=200,
|
|
73
73
|
json={
|
|
74
74
|
"PageItems": [
|
|
@@ -132,7 +132,7 @@ class TestContextGroundingService:
|
|
|
132
132
|
version: str,
|
|
133
133
|
) -> None:
|
|
134
134
|
httpx_mock.add_response(
|
|
135
|
-
url=f"{base_url}{org}{tenant}/orchestrator_/api/FoldersNavigation/GetFoldersForCurrentUser?searchText=test-folder-path&take=
|
|
135
|
+
url=f"{base_url}{org}{tenant}/orchestrator_/api/FoldersNavigation/GetFoldersForCurrentUser?searchText=test-folder-path&skip=0&take=20",
|
|
136
136
|
status_code=200,
|
|
137
137
|
json={
|
|
138
138
|
"PageItems": [
|
|
@@ -162,7 +162,7 @@ class TestContextGroundingService:
|
|
|
162
162
|
)
|
|
163
163
|
|
|
164
164
|
httpx_mock.add_response(
|
|
165
|
-
url=f"{base_url}{org}{tenant}/orchestrator_/api/FoldersNavigation/GetFoldersForCurrentUser?searchText=test-folder-path&take=
|
|
165
|
+
url=f"{base_url}{org}{tenant}/orchestrator_/api/FoldersNavigation/GetFoldersForCurrentUser?searchText=test-folder-path&skip=0&take=20",
|
|
166
166
|
status_code=200,
|
|
167
167
|
json={
|
|
168
168
|
"PageItems": [
|
|
@@ -225,7 +225,7 @@ class TestContextGroundingService:
|
|
|
225
225
|
version: str,
|
|
226
226
|
) -> None:
|
|
227
227
|
httpx_mock.add_response(
|
|
228
|
-
url=f"{base_url}{org}{tenant}/orchestrator_/api/FoldersNavigation/GetFoldersForCurrentUser?searchText=test-folder-path&take=
|
|
228
|
+
url=f"{base_url}{org}{tenant}/orchestrator_/api/FoldersNavigation/GetFoldersForCurrentUser?searchText=test-folder-path&skip=0&take=20",
|
|
229
229
|
status_code=200,
|
|
230
230
|
json={
|
|
231
231
|
"PageItems": [
|
|
@@ -285,7 +285,7 @@ class TestContextGroundingService:
|
|
|
285
285
|
version: str,
|
|
286
286
|
) -> None:
|
|
287
287
|
httpx_mock.add_response(
|
|
288
|
-
url=f"{base_url}{org}{tenant}/orchestrator_/api/FoldersNavigation/GetFoldersForCurrentUser?searchText=test-folder-path&take=
|
|
288
|
+
url=f"{base_url}{org}{tenant}/orchestrator_/api/FoldersNavigation/GetFoldersForCurrentUser?searchText=test-folder-path&skip=0&take=20",
|
|
289
289
|
status_code=200,
|
|
290
290
|
json={
|
|
291
291
|
"PageItems": [
|
|
@@ -296,7 +296,6 @@ class TestContextGroundingService:
|
|
|
296
296
|
]
|
|
297
297
|
},
|
|
298
298
|
)
|
|
299
|
-
|
|
300
299
|
httpx_mock.add_response(
|
|
301
300
|
url=f"{base_url}{org}{tenant}/ecs_/v2/indexes?$filter=Name eq 'test-index'&$expand=dataSource",
|
|
302
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]
|