uipath 2.0.57__tar.gz → 2.0.59__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.

Files changed (189) hide show
  1. {uipath-2.0.57 → uipath-2.0.59}/PKG-INFO +1 -1
  2. uipath-2.0.59/docs/core/attachments.md +1 -0
  3. {uipath-2.0.57 → uipath-2.0.59}/docs/core/traced.md +1 -1
  4. uipath-2.0.59/docs/overrides/partials/actions.html +11 -0
  5. {uipath-2.0.57 → uipath-2.0.59}/docs/stylesheets/extra.css +11 -2
  6. {uipath-2.0.57 → uipath-2.0.59}/pyproject.toml +1 -1
  7. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_cli/_runtime/_runtime.py +13 -0
  8. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_services/attachments_service.py +236 -96
  9. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_services/context_grounding_service.py +5 -2
  10. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_services/folder_service.py +21 -15
  11. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_services/jobs_service.py +293 -58
  12. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_utils/constants.py +3 -0
  13. uipath-2.0.59/src/uipath/tracing/__init__.py +4 -0
  14. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/tracing/_traced.py +0 -5
  15. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/tracing/_utils.py +6 -5
  16. {uipath-2.0.57 → uipath-2.0.59}/tests/sdk/services/test_attachments_service.py +379 -21
  17. {uipath-2.0.57 → uipath-2.0.59}/tests/sdk/services/test_folder_service.py +82 -3
  18. uipath-2.0.59/tests/sdk/services/test_jobs_service.py +931 -0
  19. {uipath-2.0.57 → uipath-2.0.59}/tests/tracing/test_span_utils.py +1 -0
  20. {uipath-2.0.57 → uipath-2.0.59}/uv.lock +1699 -1697
  21. uipath-2.0.57/docs/core/attachments.md +0 -86
  22. uipath-2.0.57/docs/overrides/partials/actions.html +0 -6
  23. uipath-2.0.57/src/uipath/tracing/__init__.py +0 -3
  24. uipath-2.0.57/tests/sdk/services/test_jobs_service.py +0 -475
  25. {uipath-2.0.57 → uipath-2.0.59}/.cursorrules +0 -0
  26. {uipath-2.0.57 → uipath-2.0.59}/.editorconfig +0 -0
  27. {uipath-2.0.57 → uipath-2.0.59}/.gitattributes +0 -0
  28. {uipath-2.0.57 → uipath-2.0.59}/.github/workflows/cd.yml +0 -0
  29. {uipath-2.0.57 → uipath-2.0.59}/.github/workflows/ci.yml +0 -0
  30. {uipath-2.0.57 → uipath-2.0.59}/.github/workflows/commitlint.yml +0 -0
  31. {uipath-2.0.57 → uipath-2.0.59}/.github/workflows/lint.yml +0 -0
  32. {uipath-2.0.57 → uipath-2.0.59}/.github/workflows/publish-dev.yml +0 -0
  33. {uipath-2.0.57 → uipath-2.0.59}/.github/workflows/publish-docs.yml +0 -0
  34. {uipath-2.0.57 → uipath-2.0.59}/.github/workflows/slack.yml +0 -0
  35. {uipath-2.0.57 → uipath-2.0.59}/.github/workflows/test.yml +0 -0
  36. {uipath-2.0.57 → uipath-2.0.59}/.gitignore +0 -0
  37. {uipath-2.0.57 → uipath-2.0.59}/.pre-commit-config.yaml +0 -0
  38. {uipath-2.0.57 → uipath-2.0.59}/.python-version +0 -0
  39. {uipath-2.0.57 → uipath-2.0.59}/.vscode/extensions.json +0 -0
  40. {uipath-2.0.57 → uipath-2.0.59}/.vscode/settings.json +0 -0
  41. {uipath-2.0.57 → uipath-2.0.59}/CONTRIBUTING.md +0 -0
  42. {uipath-2.0.57 → uipath-2.0.59}/LICENSE +0 -0
  43. {uipath-2.0.57 → uipath-2.0.59}/README.md +0 -0
  44. {uipath-2.0.57 → uipath-2.0.59}/docs/CONTRIBUTING.md +0 -0
  45. {uipath-2.0.57 → uipath-2.0.59}/docs/FAQ.md +0 -0
  46. {uipath-2.0.57 → uipath-2.0.59}/docs/assets/env-preparation-failed-dark.png +0 -0
  47. {uipath-2.0.57 → uipath-2.0.59}/docs/assets/env-preparation-failed-light.png +0 -0
  48. {uipath-2.0.57 → uipath-2.0.59}/docs/assets/favicon.png +0 -0
  49. {uipath-2.0.57 → uipath-2.0.59}/docs/assets/logo-dark.svg +0 -0
  50. {uipath-2.0.57 → uipath-2.0.59}/docs/assets/logo-light.svg +0 -0
  51. {uipath-2.0.57 → uipath-2.0.59}/docs/cli/index.md +0 -0
  52. {uipath-2.0.57 → uipath-2.0.59}/docs/core/actions.md +0 -0
  53. {uipath-2.0.57 → uipath-2.0.59}/docs/core/assets/cloud_env_var_dark.gif +0 -0
  54. {uipath-2.0.57 → uipath-2.0.59}/docs/core/assets/cloud_env_var_light.gif +0 -0
  55. {uipath-2.0.57 → uipath-2.0.59}/docs/core/assets/cloud_env_var_secret_dark.png +0 -0
  56. {uipath-2.0.57 → uipath-2.0.59}/docs/core/assets/cloud_env_var_secret_light.png +0 -0
  57. {uipath-2.0.57 → uipath-2.0.59}/docs/core/assets/copy_path_dark.png +0 -0
  58. {uipath-2.0.57 → uipath-2.0.59}/docs/core/assets/copy_path_light.png +0 -0
  59. {uipath-2.0.57 → uipath-2.0.59}/docs/core/assets.md +0 -0
  60. {uipath-2.0.57 → uipath-2.0.59}/docs/core/buckets.md +0 -0
  61. {uipath-2.0.57 → uipath-2.0.59}/docs/core/connections.md +0 -0
  62. {uipath-2.0.57 → uipath-2.0.59}/docs/core/context_grounding.md +0 -0
  63. {uipath-2.0.57 → uipath-2.0.59}/docs/core/environment_variables.md +0 -0
  64. {uipath-2.0.57 → uipath-2.0.59}/docs/core/getting_started.md +0 -0
  65. {uipath-2.0.57 → uipath-2.0.59}/docs/core/jobs.md +0 -0
  66. {uipath-2.0.57 → uipath-2.0.59}/docs/core/processes.md +0 -0
  67. {uipath-2.0.57 → uipath-2.0.59}/docs/core/queues.md +0 -0
  68. {uipath-2.0.57 → uipath-2.0.59}/docs/hooks.py +0 -0
  69. {uipath-2.0.57 → uipath-2.0.59}/docs/javascripts/extra.js +0 -0
  70. {uipath-2.0.57 → uipath-2.0.59}/docs/langchain/chat_models.md +0 -0
  71. {uipath-2.0.57 → uipath-2.0.59}/docs/langchain/context_grounding.md +0 -0
  72. {uipath-2.0.57 → uipath-2.0.59}/docs/langchain/human_in_the_loop.md +0 -0
  73. {uipath-2.0.57 → uipath-2.0.59}/docs/overrides/partials/logo.html +0 -0
  74. {uipath-2.0.57 → uipath-2.0.59}/docs/release_policy.md +0 -0
  75. {uipath-2.0.57 → uipath-2.0.59}/justfile +0 -0
  76. {uipath-2.0.57 → uipath-2.0.59}/mkdocs.yml +0 -0
  77. {uipath-2.0.57 → uipath-2.0.59}/py.typed +0 -0
  78. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/__init__.py +0 -0
  79. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_cli/README.md +0 -0
  80. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_cli/__init__.py +0 -0
  81. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_cli/_auth/_auth_server.py +0 -0
  82. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_cli/_auth/_models.py +0 -0
  83. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_cli/_auth/_oidc_utils.py +0 -0
  84. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_cli/_auth/_portal_service.py +0 -0
  85. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_cli/_auth/_utils.py +0 -0
  86. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_cli/_auth/auth_config.json +0 -0
  87. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_cli/_auth/index.html +0 -0
  88. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_cli/_auth/localhost.crt +0 -0
  89. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_cli/_auth/localhost.key +0 -0
  90. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_cli/_runtime/_contracts.py +0 -0
  91. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_cli/_runtime/_logging.py +0 -0
  92. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_cli/_templates/.psmdcp.template +0 -0
  93. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_cli/_templates/.rels.template +0 -0
  94. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_cli/_templates/[Content_Types].xml.template +0 -0
  95. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_cli/_templates/main.py.template +0 -0
  96. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_cli/_templates/package.nuspec.template +0 -0
  97. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_cli/_utils/_common.py +0 -0
  98. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_cli/_utils/_console.py +0 -0
  99. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_cli/_utils/_folders.py +0 -0
  100. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_cli/_utils/_input_args.py +0 -0
  101. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_cli/_utils/_parse_ast.py +0 -0
  102. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_cli/_utils/_processes.py +0 -0
  103. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_cli/cli_auth.py +0 -0
  104. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_cli/cli_deploy.py +0 -0
  105. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_cli/cli_init.py +0 -0
  106. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_cli/cli_invoke.py +0 -0
  107. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_cli/cli_new.py +0 -0
  108. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_cli/cli_pack.py +0 -0
  109. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_cli/cli_publish.py +0 -0
  110. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_cli/cli_run.py +0 -0
  111. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_cli/middlewares.py +0 -0
  112. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_cli/spinner.py +0 -0
  113. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_config.py +0 -0
  114. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_execution_context.py +0 -0
  115. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_folder_context.py +0 -0
  116. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_services/__init__.py +0 -0
  117. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_services/_base_service.py +0 -0
  118. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_services/actions_service.py +0 -0
  119. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_services/api_client.py +0 -0
  120. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_services/assets_service.py +0 -0
  121. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_services/buckets_service.py +0 -0
  122. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_services/connections_service.py +0 -0
  123. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_services/llm_gateway_service.py +0 -0
  124. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_services/processes_service.py +0 -0
  125. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_services/queues_service.py +0 -0
  126. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_uipath.py +0 -0
  127. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_utils/__init__.py +0 -0
  128. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_utils/_endpoint.py +0 -0
  129. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_utils/_infer_bindings.py +0 -0
  130. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_utils/_logs.py +0 -0
  131. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_utils/_read_overwrites.py +0 -0
  132. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_utils/_request_override.py +0 -0
  133. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_utils/_request_spec.py +0 -0
  134. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_utils/_url.py +0 -0
  135. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/_utils/_user_agent.py +0 -0
  136. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/models/__init__.py +0 -0
  137. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/models/action_schema.py +0 -0
  138. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/models/actions.py +0 -0
  139. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/models/assets.py +0 -0
  140. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/models/attachment.py +0 -0
  141. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/models/buckets.py +0 -0
  142. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/models/connections.py +0 -0
  143. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/models/context_grounding.py +0 -0
  144. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/models/context_grounding_index.py +0 -0
  145. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/models/errors.py +0 -0
  146. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/models/exceptions.py +0 -0
  147. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/models/interrupt_models.py +0 -0
  148. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/models/job.py +0 -0
  149. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/models/llm_gateway.py +0 -0
  150. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/models/processes.py +0 -0
  151. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/models/queues.py +0 -0
  152. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/py.typed +0 -0
  153. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/telemetry/__init__.py +0 -0
  154. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/telemetry/_constants.py +0 -0
  155. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/telemetry/_track.py +0 -0
  156. {uipath-2.0.57 → uipath-2.0.59}/src/uipath/tracing/_otel_exporters.py +0 -0
  157. {uipath-2.0.57 → uipath-2.0.59}/tests/__init__.py +0 -0
  158. {uipath-2.0.57 → uipath-2.0.59}/tests/cli/conftest.py +0 -0
  159. {uipath-2.0.57 → uipath-2.0.59}/tests/cli/mocks/pyproject.toml +0 -0
  160. {uipath-2.0.57 → uipath-2.0.59}/tests/cli/mocks/simple_script.py +0 -0
  161. {uipath-2.0.57 → uipath-2.0.59}/tests/cli/mocks/uipath-mock.json +0 -0
  162. {uipath-2.0.57 → uipath-2.0.59}/tests/cli/mocks/uipath-simple-script-mock.json +0 -0
  163. {uipath-2.0.57 → uipath-2.0.59}/tests/cli/test_init.py +0 -0
  164. {uipath-2.0.57 → uipath-2.0.59}/tests/cli/test_invoke.py +0 -0
  165. {uipath-2.0.57 → uipath-2.0.59}/tests/cli/test_new.py +0 -0
  166. {uipath-2.0.57 → uipath-2.0.59}/tests/cli/test_pack.py +0 -0
  167. {uipath-2.0.57 → uipath-2.0.59}/tests/cli/test_publish.py +0 -0
  168. {uipath-2.0.57 → uipath-2.0.59}/tests/cli/test_run.py +0 -0
  169. {uipath-2.0.57 → uipath-2.0.59}/tests/cli/utils/project_details.py +0 -0
  170. {uipath-2.0.57 → uipath-2.0.59}/tests/cli/utils/uipath_json.py +0 -0
  171. {uipath-2.0.57 → uipath-2.0.59}/tests/conftest.py +0 -0
  172. {uipath-2.0.57 → uipath-2.0.59}/tests/sdk/services/conftest.py +0 -0
  173. {uipath-2.0.57 → uipath-2.0.59}/tests/sdk/services/test_actions_service.py +0 -0
  174. {uipath-2.0.57 → uipath-2.0.59}/tests/sdk/services/test_api_client.py +0 -0
  175. {uipath-2.0.57 → uipath-2.0.59}/tests/sdk/services/test_assets_service.py +0 -0
  176. {uipath-2.0.57 → uipath-2.0.59}/tests/sdk/services/test_base_service.py +0 -0
  177. {uipath-2.0.57 → uipath-2.0.59}/tests/sdk/services/test_buckets_service.py +0 -0
  178. {uipath-2.0.57 → uipath-2.0.59}/tests/sdk/services/test_connections_service.py +0 -0
  179. {uipath-2.0.57 → uipath-2.0.59}/tests/sdk/services/test_context_grounding_service.py +0 -0
  180. {uipath-2.0.57 → uipath-2.0.59}/tests/sdk/services/test_llm_integration.py +0 -0
  181. {uipath-2.0.57 → uipath-2.0.59}/tests/sdk/services/test_llm_service.py +0 -0
  182. {uipath-2.0.57 → uipath-2.0.59}/tests/sdk/services/test_processes_service.py +0 -0
  183. {uipath-2.0.57 → uipath-2.0.59}/tests/sdk/services/test_queues_service.py +0 -0
  184. {uipath-2.0.57 → uipath-2.0.59}/tests/sdk/services/test_uipath_llm_integration.py +0 -0
  185. {uipath-2.0.57 → uipath-2.0.59}/tests/sdk/test_config.py +0 -0
  186. {uipath-2.0.57 → uipath-2.0.59}/tests/sdk/test_overwrites.py +0 -0
  187. {uipath-2.0.57 → uipath-2.0.59}/tests/tracing/test_otel_exporters.py +0 -0
  188. {uipath-2.0.57 → uipath-2.0.59}/tests/tracing/test_traced.py +0 -0
  189. {uipath-2.0.57 → uipath-2.0.59}/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.57
3
+ Version: 2.0.59
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
@@ -0,0 +1 @@
1
+ ::: uipath._services.attachments_service
@@ -9,7 +9,7 @@ You can view the traces of an Orchestrator job by going to the Jobs page, click
9
9
  Apply the `@traced()` decorator to any function (sync, async, generator, or async generator) to automatically record its execution as a trace span.
10
10
 
11
11
  ```python hl_lines="3 7"
12
- from uipath.tracing._traced import traced
12
+ from uipath.tracing import traced
13
13
 
14
14
  @traced()
15
15
  def my_function(x, y):
@@ -0,0 +1,11 @@
1
+ {% set title = ("[" + (page.title or config.site_name) + "] Your title here") | urlencode %}
2
+ {% set body = ("Page link:: " + config.site_url + page.url + "\n\n ## My Issue/Suggestion") | urlencode %}
3
+ <a href="https://github.com/UiPath/uipath-python/issues/new?title={{ title }}&body={{ body }}"
4
+ class="md-content__button skip-link-icon report-issue-link">
5
+ <svg viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
6
+ <path fill-rule="evenodd" clip-rule="evenodd"
7
+ d="M17.19 8H20V10H17.91C17.96 10.33 18 10.66 18 11V12H20V14H18V15C18 15.34 17.96 15.67 17.91 16H20V18H17.19C16.15 19.79 14.22 21 12 21C9.78 21 7.85 19.79 6.81 18H4V16H6.09C6.04 15.67 6 15.34 6 15V14H4V12H6V11C6 10.66 6.04 10.33 6.09 10H4V8H6.81C7.26 7.22 7.88 6.55 8.62 6.04L7 4.41L8.41 3L10.59 5.17C11.04 5.06 11.51 5 12 5C12.49 5 12.96 5.06 13.42 5.17L15.59 3L17 4.41L15.37 6.04C16.12 6.55 16.74 7.22 17.19 8ZM16 15V12V11C16 10.78 15.97 10.53 15.93 10.31L15.83 9.66L15.45 9.01C15.15 8.48 14.74 8.04 14.24 7.7L13.63 7.28L12.95 7.12C12.63 7.04 12.32 7 12 7C11.69 7 11.37 7.04 11.06 7.12L10.32 7.3L9.75 7.69C9.26 8.03 8.84 8.48 8.54 9L8.17 9.65L8.07 10.3C8.03 10.52 8 10.77 8 11V15C8 15.23 8.03 15.48 8.07 15.71L8.17 16.36L8.54 17C9.26 18.23 10.58 19 12 19C13.42 19 14.74 18.24 15.46 17L15.83 16.35L15.93 15.7C15.97 15.47 16 15.22 16 15ZM10 14H14V16H10V14ZM14 10H10V12H14V10Z" />
8
+ </svg>
9
+
10
+ Report an issue
11
+ </a>
@@ -150,6 +150,15 @@ a[href^="https://"]:not(.md-source):not(.skip-link-icon) {
150
150
  }
151
151
 
152
152
  .report-issue-link {
153
- text-decoration: underline;
154
- text-decoration-style: wavy;
153
+ margin-block: 0.8rem;
154
+ font-size: 0.7rem;
155
+ line-height: 1;
156
+ display: flex;
157
+ align-items: center;
158
+
159
+ svg {
160
+ margin-top: -0.1rem;
161
+ width: 0.7rem;
162
+ height: 0.7rem;
163
+ }
155
164
  }
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "uipath"
3
- version = "2.0.57"
3
+ version = "2.0.59"
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"
@@ -8,6 +8,12 @@ import os
8
8
  from dataclasses import asdict, is_dataclass
9
9
  from typing import Any, Dict, Optional, Type, TypeVar, cast, get_type_hints
10
10
 
11
+ from opentelemetry import trace
12
+ from opentelemetry.sdk.trace import TracerProvider
13
+ from opentelemetry.sdk.trace.export import BatchSpanProcessor
14
+
15
+ from uipath.tracing import LlmOpsHttpExporter
16
+
11
17
  from ._contracts import (
12
18
  UiPathBaseRuntime,
13
19
  UiPathErrorCategory,
@@ -36,6 +42,11 @@ class UiPathRuntime(UiPathBaseRuntime):
36
42
  await self.validate()
37
43
 
38
44
  try:
45
+ trace.set_tracer_provider(TracerProvider())
46
+ trace.get_tracer_provider().add_span_processor( # type: ignore
47
+ BatchSpanProcessor(LlmOpsHttpExporter())
48
+ )
49
+
39
50
  if self.context.entrypoint is None:
40
51
  return None
41
52
 
@@ -62,6 +73,8 @@ class UiPathRuntime(UiPathBaseRuntime):
62
73
  f"Error: {str(e)}",
63
74
  UiPathErrorCategory.SYSTEM,
64
75
  ) from e
76
+ finally:
77
+ trace.get_tracer_provider().shutdown() # type: ignore
65
78
 
66
79
  async def validate(self) -> None:
67
80
  """Validate runtime inputs."""
@@ -1,12 +1,17 @@
1
+ import os
2
+ import shutil
3
+ import tempfile
1
4
  import uuid
5
+ from pathlib import Path
2
6
  from typing import Any, Dict, Optional, Union, overload
3
7
 
4
- from httpx import request
8
+ import httpx
5
9
 
6
10
  from .._config import Config
7
11
  from .._execution_context import ExecutionContext
8
12
  from .._folder_context import FolderContext
9
13
  from .._utils import Endpoint, RequestSpec, header_folder
14
+ from .._utils.constants import TEMP_ATTACHMENTS_FOLDER
10
15
  from ..tracing._traced import traced
11
16
  from ._base_service import BaseService
12
17
 
@@ -35,6 +40,7 @@ class AttachmentsService(FolderContext, BaseService):
35
40
 
36
41
  def __init__(self, config: Config, execution_context: ExecutionContext) -> None:
37
42
  super().__init__(config=config, execution_context=execution_context)
43
+ self._temp_dir = os.path.join(tempfile.gettempdir(), TEMP_ATTACHMENTS_FOLDER)
38
44
 
39
45
  @traced(name="attachments_download", run_type="uipath")
40
46
  def download(
@@ -48,6 +54,12 @@ class AttachmentsService(FolderContext, BaseService):
48
54
  """Download an attachment.
49
55
 
50
56
  This method downloads an attachment from UiPath to a local file.
57
+ If the attachment is not found in UiPath (404 error), it will check
58
+ for a local file in the temporary directory that matches the UUID.
59
+
60
+ Note:
61
+ The local file fallback functionality is intended for local development
62
+ and debugging purposes only.
51
63
 
52
64
  Args:
53
65
  key (uuid.UUID): The key of the attachment to download.
@@ -59,7 +71,7 @@ class AttachmentsService(FolderContext, BaseService):
59
71
  str: The name of the downloaded attachment.
60
72
 
61
73
  Raises:
62
- Exception: If the download fails.
74
+ Exception: If the download fails and no local file is found.
63
75
 
64
76
  Examples:
65
77
  ```python
@@ -74,42 +86,75 @@ class AttachmentsService(FolderContext, BaseService):
74
86
  print(f"Downloaded attachment: {attachment_name}")
75
87
  ```
76
88
  """
77
- spec = self._retrieve_download_uri_spec(
78
- key=key,
79
- folder_key=folder_key,
80
- folder_path=folder_path,
81
- )
82
-
83
- result = self.request(
84
- spec.method,
85
- url=spec.endpoint,
86
- params=spec.params,
87
- headers=spec.headers,
88
- ).json()
89
-
90
- # Get the attachment name
91
- attachment_name = result["Name"]
92
-
93
- download_uri = result["BlobFileAccess"]["Uri"]
94
- headers = {
95
- key: value
96
- for key, value in zip(
97
- result["BlobFileAccess"]["Headers"]["Keys"],
98
- result["BlobFileAccess"]["Headers"]["Values"],
99
- strict=False,
89
+ try:
90
+ spec = self._retrieve_download_uri_spec(
91
+ key=key,
92
+ folder_key=folder_key,
93
+ folder_path=folder_path,
100
94
  )
101
- }
102
95
 
103
- with open(destination_path, "wb") as file:
104
- if result["BlobFileAccess"]["RequiresAuth"]:
105
- file_content = self.request(
106
- "GET", download_uri, headers=headers
107
- ).content
108
- else:
109
- file_content = request("GET", download_uri, headers=headers).content
110
- file.write(file_content)
96
+ result = self.request(
97
+ spec.method,
98
+ url=spec.endpoint,
99
+ params=spec.params,
100
+ headers=spec.headers,
101
+ ).json()
102
+
103
+ # Get the attachment name
104
+ attachment_name = result["Name"]
105
+
106
+ download_uri = result["BlobFileAccess"]["Uri"]
107
+ headers = {
108
+ key: value
109
+ for key, value in zip(
110
+ result["BlobFileAccess"]["Headers"]["Keys"],
111
+ result["BlobFileAccess"]["Headers"]["Values"],
112
+ strict=False,
113
+ )
114
+ }
111
115
 
112
- return attachment_name
116
+ with open(destination_path, "wb") as file:
117
+ if result["BlobFileAccess"]["RequiresAuth"]:
118
+ response = self.request(
119
+ "GET", download_uri, headers=headers, stream=True
120
+ )
121
+ for chunk in response.iter_bytes(chunk_size=8192):
122
+ file.write(chunk)
123
+ else:
124
+ with httpx.Client() as client:
125
+ with client.stream(
126
+ "GET", download_uri, headers=headers
127
+ ) as response:
128
+ for chunk in response.iter_bytes(chunk_size=8192):
129
+ file.write(chunk)
130
+
131
+ return attachment_name
132
+ except Exception as e:
133
+ # If not found in UiPath, check local storage
134
+ if "404" in str(e):
135
+ # Check if file exists in temp directory
136
+ if os.path.exists(self._temp_dir):
137
+ # Look for any file starting with our UUID
138
+ pattern = f"{key}_*"
139
+ matching_files = list(Path(self._temp_dir).glob(pattern))
140
+
141
+ if matching_files:
142
+ # Get the full filename
143
+ local_file = matching_files[0]
144
+
145
+ # Extract the original name from the filename (part after UUID_)
146
+ file_name = os.path.basename(local_file)
147
+ original_name = file_name[len(f"{key}_") :]
148
+
149
+ # Copy the file to the destination
150
+ shutil.copy2(local_file, destination_path)
151
+
152
+ return original_name
153
+
154
+ # Re-raise the original exception if we can't find it locally
155
+ raise Exception(
156
+ f"Attachment with key {key} not found in UiPath or local storage"
157
+ ) from e
113
158
 
114
159
  @traced(name="attachments_download", run_type="uipath")
115
160
  async def download_async(
@@ -123,6 +168,12 @@ class AttachmentsService(FolderContext, BaseService):
123
168
  """Download an attachment asynchronously.
124
169
 
125
170
  This method asynchronously downloads an attachment from UiPath to a local file.
171
+ If the attachment is not found in UiPath (404 error), it will check
172
+ for a local file in the temporary directory that matches the UUID.
173
+
174
+ Note:
175
+ The local file fallback functionality is intended for local development
176
+ and debugging purposes only.
126
177
 
127
178
  Args:
128
179
  key (uuid.UUID): The key of the attachment to download.
@@ -134,7 +185,7 @@ class AttachmentsService(FolderContext, BaseService):
134
185
  str: The name of the downloaded attachment.
135
186
 
136
187
  Raises:
137
- Exception: If the download fails.
188
+ Exception: If the download fails and no local file is found.
138
189
 
139
190
  Examples:
140
191
  ```python
@@ -151,44 +202,77 @@ class AttachmentsService(FolderContext, BaseService):
151
202
  print(f"Downloaded attachment: {attachment_name}")
152
203
  ```
153
204
  """
154
- spec = self._retrieve_download_uri_spec(
155
- key=key,
156
- folder_key=folder_key,
157
- folder_path=folder_path,
158
- )
159
-
160
- result = (
161
- await self.request_async(
162
- spec.method,
163
- url=spec.endpoint,
164
- params=spec.params,
165
- headers=spec.headers,
166
- )
167
- ).json()
168
-
169
- # Get the attachment name
170
- attachment_name = result["Name"]
171
-
172
- download_uri = result["BlobFileAccess"]["Uri"]
173
- headers = {
174
- key: value
175
- for key, value in zip(
176
- result["BlobFileAccess"]["Headers"]["Keys"],
177
- result["BlobFileAccess"]["Headers"]["Values"],
178
- strict=False,
205
+ try:
206
+ spec = self._retrieve_download_uri_spec(
207
+ key=key,
208
+ folder_key=folder_key,
209
+ folder_path=folder_path,
179
210
  )
180
- }
181
211
 
182
- with open(destination_path, "wb") as file:
183
- if result["BlobFileAccess"]["RequiresAuth"]:
184
- response = await self.request_async(
185
- "GET", download_uri, headers=headers
212
+ result = (
213
+ await self.request_async(
214
+ spec.method,
215
+ url=spec.endpoint,
216
+ params=spec.params,
217
+ headers=spec.headers,
186
218
  )
187
- file.write(response.content)
188
- else:
189
- file.write(request("GET", download_uri, headers=headers).content)
219
+ ).json()
220
+
221
+ # Get the attachment name
222
+ attachment_name = result["Name"]
223
+
224
+ download_uri = result["BlobFileAccess"]["Uri"]
225
+ headers = {
226
+ key: value
227
+ for key, value in zip(
228
+ result["BlobFileAccess"]["Headers"]["Keys"],
229
+ result["BlobFileAccess"]["Headers"]["Values"],
230
+ strict=False,
231
+ )
232
+ }
190
233
 
191
- return attachment_name
234
+ with open(destination_path, "wb") as file:
235
+ if result["BlobFileAccess"]["RequiresAuth"]:
236
+ response = await self.request_async(
237
+ "GET", download_uri, headers=headers, stream=True
238
+ )
239
+ async for chunk in response.aiter_bytes(chunk_size=8192):
240
+ file.write(chunk)
241
+ else:
242
+ async with httpx.AsyncClient() as client:
243
+ async with client.stream(
244
+ "GET", download_uri, headers=headers
245
+ ) as response:
246
+ async for chunk in response.aiter_bytes(chunk_size=8192):
247
+ file.write(chunk)
248
+
249
+ return attachment_name
250
+ except Exception as e:
251
+ # If not found in UiPath, check local storage
252
+ if "404" in str(e):
253
+ # Check if file exists in temp directory
254
+ if os.path.exists(self._temp_dir):
255
+ # Look for any file starting with our UUID
256
+ pattern = f"{key}_*"
257
+ matching_files = list(Path(self._temp_dir).glob(pattern))
258
+
259
+ if matching_files:
260
+ # Get the full filename
261
+ local_file = matching_files[0]
262
+
263
+ # Extract the original name from the filename (part after UUID_)
264
+ file_name = os.path.basename(local_file)
265
+ original_name = file_name[len(f"{key}_") :]
266
+
267
+ # Copy the file to the destination
268
+ shutil.copy2(local_file, destination_path)
269
+
270
+ return original_name
271
+
272
+ # Re-raise the original exception if we can't find it locally
273
+ raise Exception(
274
+ f"Attachment with key {key} not found in UiPath or local storage"
275
+ ) from e
192
276
 
193
277
  @overload
194
278
  def upload(
@@ -305,7 +389,8 @@ class AttachmentsService(FolderContext, BaseService):
305
389
  "PUT", upload_uri, headers=headers, files={"file": file}
306
390
  )
307
391
  else:
308
- request("PUT", upload_uri, headers=headers, files={"file": file})
392
+ with httpx.Client() as client:
393
+ client.put(upload_uri, headers=headers, files={"file": file})
309
394
  else:
310
395
  # Upload from memory
311
396
  # Convert string to bytes if needed
@@ -315,7 +400,8 @@ class AttachmentsService(FolderContext, BaseService):
315
400
  if result["BlobFileAccess"]["RequiresAuth"]:
316
401
  self.request("PUT", upload_uri, headers=headers, content=content)
317
402
  else:
318
- request("PUT", upload_uri, headers=headers, content=content)
403
+ with httpx.Client() as client:
404
+ client.put(upload_uri, headers=headers, content=content)
319
405
 
320
406
  return attachment_key
321
407
 
@@ -438,7 +524,8 @@ class AttachmentsService(FolderContext, BaseService):
438
524
  "PUT", upload_uri, headers=headers, files={"file": file}
439
525
  )
440
526
  else:
441
- request("PUT", upload_uri, headers=headers, files={"file": file})
527
+ with httpx.Client() as client:
528
+ client.put(upload_uri, headers=headers, files={"file": file})
442
529
  else:
443
530
  # Upload from memory
444
531
  # Convert string to bytes if needed
@@ -450,7 +537,8 @@ class AttachmentsService(FolderContext, BaseService):
450
537
  "PUT", upload_uri, headers=headers, content=content
451
538
  )
452
539
  else:
453
- request("PUT", upload_uri, headers=headers, content=content)
540
+ with httpx.Client() as client:
541
+ client.put(upload_uri, headers=headers, content=content)
454
542
 
455
543
  return attachment_key
456
544
 
@@ -465,6 +553,12 @@ class AttachmentsService(FolderContext, BaseService):
465
553
  """Delete an attachment.
466
554
 
467
555
  This method deletes an attachment from UiPath.
556
+ If the attachment is not found in UiPath (404 error), it will check
557
+ for a local file in the temporary directory that matches the UUID.
558
+
559
+ Note:
560
+ The local file fallback functionality is intended for local development
561
+ and debugging purposes only.
468
562
 
469
563
  Args:
470
564
  key (uuid.UUID): The key of the attachment to delete.
@@ -472,7 +566,7 @@ class AttachmentsService(FolderContext, BaseService):
472
566
  folder_path (Optional[str]): The path of the folder. Override the default one set in the SDK config.
473
567
 
474
568
  Raises:
475
- Exception: If the deletion fails.
569
+ Exception: If the deletion fails and no local file is found.
476
570
 
477
571
  Examples:
478
572
  ```python
@@ -486,17 +580,37 @@ class AttachmentsService(FolderContext, BaseService):
486
580
  print("Attachment deleted successfully")
487
581
  ```
488
582
  """
489
- spec = self._delete_attachment_spec(
490
- key=key,
491
- folder_key=folder_key,
492
- folder_path=folder_path,
493
- )
583
+ try:
584
+ spec = self._delete_attachment_spec(
585
+ key=key,
586
+ folder_key=folder_key,
587
+ folder_path=folder_path,
588
+ )
494
589
 
495
- self.request(
496
- spec.method,
497
- url=spec.endpoint,
498
- headers=spec.headers,
499
- )
590
+ self.request(
591
+ spec.method,
592
+ url=spec.endpoint,
593
+ headers=spec.headers,
594
+ )
595
+ except Exception as e:
596
+ # If not found in UiPath, check local storage
597
+ if "404" in str(e):
598
+ # Check if file exists in temp directory
599
+ if os.path.exists(self._temp_dir):
600
+ # Look for any file starting with our UUID
601
+ pattern = f"{key}_*"
602
+ matching_files = list(Path(self._temp_dir).glob(pattern))
603
+
604
+ if matching_files:
605
+ # Delete all matching files
606
+ for file_path in matching_files:
607
+ os.remove(file_path)
608
+ return
609
+
610
+ # Re-raise the original exception if we can't find it locally
611
+ raise Exception(
612
+ f"Attachment with key {key} not found in UiPath or local storage"
613
+ ) from e
500
614
 
501
615
  @traced(name="attachments_delete", run_type="uipath")
502
616
  async def delete_async(
@@ -509,6 +623,12 @@ class AttachmentsService(FolderContext, BaseService):
509
623
  """Delete an attachment asynchronously.
510
624
 
511
625
  This method asynchronously deletes an attachment from UiPath.
626
+ If the attachment is not found in UiPath (404 error), it will check
627
+ for a local file in the temporary directory that matches the UUID.
628
+
629
+ Note:
630
+ The local file fallback functionality is intended for local development
631
+ and debugging purposes only.
512
632
 
513
633
  Args:
514
634
  key (uuid.UUID): The key of the attachment to delete.
@@ -516,7 +636,7 @@ class AttachmentsService(FolderContext, BaseService):
516
636
  folder_path (Optional[str]): The path of the folder. Override the default one set in the SDK config.
517
637
 
518
638
  Raises:
519
- Exception: If the deletion fails.
639
+ Exception: If the deletion fails and no local file is found.
520
640
 
521
641
  Examples:
522
642
  ```python
@@ -532,17 +652,37 @@ class AttachmentsService(FolderContext, BaseService):
532
652
  print("Attachment deleted successfully")
533
653
  ```
534
654
  """
535
- spec = self._delete_attachment_spec(
536
- key=key,
537
- folder_key=folder_key,
538
- folder_path=folder_path,
539
- )
655
+ try:
656
+ spec = self._delete_attachment_spec(
657
+ key=key,
658
+ folder_key=folder_key,
659
+ folder_path=folder_path,
660
+ )
540
661
 
541
- await self.request_async(
542
- spec.method,
543
- url=spec.endpoint,
544
- headers=spec.headers,
545
- )
662
+ await self.request_async(
663
+ spec.method,
664
+ url=spec.endpoint,
665
+ headers=spec.headers,
666
+ )
667
+ except Exception as e:
668
+ # If not found in UiPath, check local storage
669
+ if "404" in str(e):
670
+ # Check if file exists in temp directory
671
+ if os.path.exists(self._temp_dir):
672
+ # Look for any file starting with our UUID
673
+ pattern = f"{key}_*"
674
+ matching_files = list(Path(self._temp_dir).glob(pattern))
675
+
676
+ if matching_files:
677
+ # Delete all matching files
678
+ for file_path in matching_files:
679
+ os.remove(file_path)
680
+ return
681
+
682
+ # Re-raise the original exception if we can't find it locally
683
+ raise Exception(
684
+ f"Attachment with key {key} not found in UiPath or local storage"
685
+ ) from e
546
686
 
547
687
  @property
548
688
  def custom_headers(self) -> Dict[str, str]:
@@ -3,6 +3,7 @@ from typing import Any, List, Optional, Tuple, Union
3
3
 
4
4
  import httpx
5
5
  from pydantic import TypeAdapter
6
+ from typing_extensions import deprecated
6
7
 
7
8
  from .._config import Config
8
9
  from .._execution_context import ExecutionContext
@@ -234,6 +235,7 @@ class ContextGroundingService(FolderContext, BaseService):
234
235
  raise Exception("ContextGroundingIndex not found") from e
235
236
 
236
237
  @traced(name="contextgrounding_retrieve_by_id", run_type="uipath")
238
+ @deprecated("Use retrieve instead")
237
239
  def retrieve_by_id(
238
240
  self,
239
241
  id: str,
@@ -266,6 +268,7 @@ class ContextGroundingService(FolderContext, BaseService):
266
268
  ).json()
267
269
 
268
270
  @traced(name="contextgrounding_retrieve_by_id", run_type="uipath")
271
+ @deprecated("Use retrieve_async instead")
269
272
  async def retrieve_by_id_async(
270
273
  self,
271
274
  id: str,
@@ -656,11 +659,11 @@ class ContextGroundingService(FolderContext, BaseService):
656
659
 
657
660
  def _resolve_folder_key(self, folder_key, folder_path):
658
661
  if folder_key is None and folder_path is not None:
659
- folder_key = self._folders_service.retrieve_key_by_folder_path(folder_path)
662
+ folder_key = self._folders_service.retrieve_key(folder_path=folder_path)
660
663
 
661
664
  if folder_key is None and folder_path is None:
662
665
  folder_key = self._folder_key or (
663
- self._folders_service.retrieve_key_by_folder_path(self._folder_path)
666
+ self._folders_service.retrieve_key(folder_path=self._folder_path)
664
667
  if self._folder_path
665
668
  else None
666
669
  )
@@ -1,5 +1,7 @@
1
1
  from typing import Optional
2
2
 
3
+ from typing_extensions import deprecated
4
+
3
5
  from uipath.tracing._traced import traced
4
6
 
5
7
  from .._config import Config
@@ -8,20 +10,6 @@ from .._utils import Endpoint, RequestSpec
8
10
  from ._base_service import BaseService
9
11
 
10
12
 
11
- def _retrieve_spec(folder_path: str) -> RequestSpec:
12
- folder_name = folder_path.split("/")[-1]
13
- return RequestSpec(
14
- method="GET",
15
- endpoint=Endpoint(
16
- "orchestrator_/api/FoldersNavigation/GetFoldersForCurrentUser"
17
- ),
18
- params={
19
- "searchText": folder_name,
20
- "take": 1,
21
- },
22
- )
23
-
24
-
25
13
  class FolderService(BaseService):
26
14
  """Service for managing UiPath Folders.
27
15
 
@@ -34,8 +22,13 @@ class FolderService(BaseService):
34
22
  super().__init__(config=config, execution_context=execution_context)
35
23
 
36
24
  @traced(name="folder_retrieve_key_by_folder_path", run_type="uipath")
25
+ @deprecated("Use retrieve_key instead")
37
26
  def retrieve_key_by_folder_path(self, folder_path: str) -> Optional[str]:
38
- spec = _retrieve_spec(folder_path)
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
+ spec = self._retrieve_spec(folder_path)
39
32
  response = self.request(
40
33
  spec.method,
41
34
  url=spec.endpoint,
@@ -50,3 +43,16 @@ class FolderService(BaseService):
50
43
  ),
51
44
  None,
52
45
  )
46
+
47
+ def _retrieve_spec(self, folder_path: str) -> RequestSpec:
48
+ folder_name = folder_path.split("/")[-1]
49
+ return RequestSpec(
50
+ method="GET",
51
+ endpoint=Endpoint(
52
+ "orchestrator_/api/FoldersNavigation/GetFoldersForCurrentUser"
53
+ ),
54
+ params={
55
+ "searchText": folder_name,
56
+ "take": 1,
57
+ },
58
+ )