prefect-client 3.0.0rc12__tar.gz → 3.0.0rc14__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.
Files changed (205) hide show
  1. {prefect-client-3.0.0rc12/src/prefect_client.egg-info → prefect-client-3.0.0rc14}/PKG-INFO +1 -1
  2. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/requirements-client.txt +1 -0
  3. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/blocks/core.py +132 -4
  4. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/blocks/notifications.py +26 -3
  5. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/client/base.py +30 -24
  6. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/client/orchestration.py +121 -47
  7. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/client/utilities.py +4 -4
  8. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/concurrency/asyncio.py +48 -7
  9. prefect-client-3.0.0rc14/src/prefect/concurrency/context.py +24 -0
  10. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/concurrency/services.py +24 -8
  11. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/concurrency/sync.py +30 -3
  12. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/context.py +83 -23
  13. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/events/clients.py +59 -4
  14. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/events/worker.py +9 -2
  15. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/flow_engine.py +6 -3
  16. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/flows.py +166 -8
  17. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/futures.py +84 -2
  18. prefect-client-3.0.0rc14/src/prefect/profiles.toml +14 -0
  19. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/runner/runner.py +6 -1
  20. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/settings.py +35 -7
  21. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/task_engine.py +870 -291
  22. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/task_runs.py +24 -1
  23. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/task_worker.py +27 -16
  24. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/utilities/callables.py +5 -3
  25. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/utilities/importtools.py +138 -58
  26. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/utilities/schema_tools/validation.py +30 -0
  27. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/utilities/services.py +32 -0
  28. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14/src/prefect_client.egg-info}/PKG-INFO +1 -1
  29. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect_client.egg-info/SOURCES.txt +1 -0
  30. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect_client.egg-info/requires.txt +1 -0
  31. prefect-client-3.0.0rc12/src/prefect/profiles.toml +0 -3
  32. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/LICENSE +0 -0
  33. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/MANIFEST.in +0 -0
  34. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/README.md +0 -0
  35. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/requirements-dev.txt +0 -0
  36. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/requirements.txt +0 -0
  37. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/setup.cfg +0 -0
  38. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/setup.py +0 -0
  39. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/.prefectignore +0 -0
  40. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/__init__.py +0 -0
  41. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/_internal/__init__.py +0 -0
  42. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/_internal/_logging.py +0 -0
  43. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/_internal/compatibility/__init__.py +0 -0
  44. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/_internal/compatibility/deprecated.py +0 -0
  45. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/_internal/compatibility/experimental.py +0 -0
  46. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/_internal/compatibility/migration.py +0 -0
  47. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/_internal/concurrency/__init__.py +0 -0
  48. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/_internal/concurrency/api.py +0 -0
  49. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/_internal/concurrency/calls.py +0 -0
  50. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/_internal/concurrency/cancellation.py +0 -0
  51. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/_internal/concurrency/event_loop.py +0 -0
  52. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/_internal/concurrency/inspection.py +0 -0
  53. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/_internal/concurrency/primitives.py +0 -0
  54. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/_internal/concurrency/services.py +0 -0
  55. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/_internal/concurrency/threads.py +0 -0
  56. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/_internal/concurrency/waiters.py +0 -0
  57. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/_internal/integrations.py +0 -0
  58. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/_internal/pydantic/__init__.py +0 -0
  59. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/_internal/pydantic/annotations/__init__.py +0 -0
  60. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/_internal/pydantic/annotations/pendulum.py +0 -0
  61. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/_internal/pydantic/schemas.py +0 -0
  62. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/_internal/pydantic/v1_schema.py +0 -0
  63. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/_internal/pydantic/v2_schema.py +0 -0
  64. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/_internal/pydantic/v2_validated_func.py +0 -0
  65. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/_internal/pytz.py +0 -0
  66. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/_internal/retries.py +0 -0
  67. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/_internal/schemas/__init__.py +0 -0
  68. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/_internal/schemas/bases.py +0 -0
  69. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/_internal/schemas/fields.py +0 -0
  70. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/_internal/schemas/serializers.py +0 -0
  71. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/_internal/schemas/validators.py +0 -0
  72. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/_version.py +0 -0
  73. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/agent.py +0 -0
  74. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/artifacts.py +0 -0
  75. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/automations.py +0 -0
  76. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/blocks/__init__.py +0 -0
  77. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/blocks/abstract.py +0 -0
  78. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/blocks/fields.py +0 -0
  79. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/blocks/redis.py +0 -0
  80. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/blocks/system.py +0 -0
  81. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/blocks/webhook.py +0 -0
  82. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/cache_policies.py +0 -0
  83. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/client/__init__.py +0 -0
  84. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/client/cloud.py +0 -0
  85. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/client/collections.py +0 -0
  86. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/client/constants.py +0 -0
  87. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/client/schemas/__init__.py +0 -0
  88. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/client/schemas/actions.py +0 -0
  89. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/client/schemas/filters.py +0 -0
  90. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/client/schemas/objects.py +0 -0
  91. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/client/schemas/responses.py +0 -0
  92. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/client/schemas/schedules.py +0 -0
  93. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/client/schemas/sorting.py +0 -0
  94. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/client/subscriptions.py +0 -0
  95. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/client/types/__init__.py +0 -0
  96. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/client/types/flexible_schedule_list.py +0 -0
  97. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/concurrency/__init__.py +0 -0
  98. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/concurrency/events.py +0 -0
  99. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/deployments/__init__.py +0 -0
  100. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/deployments/base.py +0 -0
  101. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/deployments/deployments.py +0 -0
  102. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/deployments/flow_runs.py +0 -0
  103. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/deployments/runner.py +0 -0
  104. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/deployments/schedules.py +0 -0
  105. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/deployments/steps/__init__.py +0 -0
  106. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/deployments/steps/core.py +0 -0
  107. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/deployments/steps/pull.py +0 -0
  108. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/deployments/steps/utility.py +0 -0
  109. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/docker/__init__.py +0 -0
  110. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/docker/docker_image.py +0 -0
  111. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/engine.py +0 -0
  112. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/events/__init__.py +0 -0
  113. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/events/actions.py +0 -0
  114. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/events/cli/__init__.py +0 -0
  115. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/events/cli/automations.py +0 -0
  116. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/events/filters.py +0 -0
  117. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/events/related.py +0 -0
  118. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/events/schemas/__init__.py +0 -0
  119. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/events/schemas/automations.py +0 -0
  120. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/events/schemas/deployment_triggers.py +0 -0
  121. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/events/schemas/events.py +0 -0
  122. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/events/schemas/labelling.py +0 -0
  123. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/events/utilities.py +0 -0
  124. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/exceptions.py +0 -0
  125. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/filesystems.py +0 -0
  126. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/flow_runs.py +0 -0
  127. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/infrastructure/__init__.py +0 -0
  128. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/infrastructure/base.py +0 -0
  129. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/infrastructure/provisioners/__init__.py +0 -0
  130. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/infrastructure/provisioners/cloud_run.py +0 -0
  131. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/infrastructure/provisioners/container_instance.py +0 -0
  132. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/infrastructure/provisioners/ecs.py +0 -0
  133. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/infrastructure/provisioners/modal.py +0 -0
  134. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/input/__init__.py +0 -0
  135. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/input/actions.py +0 -0
  136. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/input/run_input.py +0 -0
  137. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/logging/__init__.py +0 -0
  138. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/logging/configuration.py +0 -0
  139. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/logging/filters.py +0 -0
  140. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/logging/formatters.py +0 -0
  141. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/logging/handlers.py +0 -0
  142. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/logging/highlighters.py +0 -0
  143. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/logging/loggers.py +0 -0
  144. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/logging/logging.yml +0 -0
  145. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/main.py +0 -0
  146. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/manifests.py +0 -0
  147. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/plugins.py +0 -0
  148. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/py.typed +0 -0
  149. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/records/__init__.py +0 -0
  150. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/records/result_store.py +0 -0
  151. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/records/store.py +0 -0
  152. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/results.py +0 -0
  153. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/runner/__init__.py +0 -0
  154. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/runner/server.py +0 -0
  155. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/runner/storage.py +0 -0
  156. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/runner/submit.py +0 -0
  157. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/runner/utils.py +0 -0
  158. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/runtime/__init__.py +0 -0
  159. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/runtime/deployment.py +0 -0
  160. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/runtime/flow_run.py +0 -0
  161. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/runtime/task_run.py +0 -0
  162. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/serializers.py +0 -0
  163. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/server/api/collections_data/views/aggregate-worker-metadata.json +0 -0
  164. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/server/api/static/prefect-logo-mark-gradient.png +0 -0
  165. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/states.py +0 -0
  166. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/task_runners.py +0 -0
  167. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/tasks.py +0 -0
  168. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/transactions.py +0 -0
  169. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/types/__init__.py +0 -0
  170. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/types/entrypoint.py +0 -0
  171. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/utilities/__init__.py +0 -0
  172. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/utilities/annotations.py +0 -0
  173. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/utilities/asyncutils.py +0 -0
  174. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/utilities/collections.py +0 -0
  175. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/utilities/compat.py +0 -0
  176. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/utilities/context.py +0 -0
  177. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/utilities/dispatch.py +0 -0
  178. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/utilities/dockerutils.py +0 -0
  179. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/utilities/engine.py +0 -0
  180. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/utilities/filesystem.py +0 -0
  181. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/utilities/hashing.py +0 -0
  182. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/utilities/math.py +0 -0
  183. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/utilities/names.py +0 -0
  184. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/utilities/processutils.py +0 -0
  185. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/utilities/pydantic.py +0 -0
  186. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/utilities/render_swagger.py +0 -0
  187. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/utilities/schema_tools/__init__.py +0 -0
  188. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/utilities/schema_tools/hydration.py +0 -0
  189. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/utilities/slugify.py +0 -0
  190. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/utilities/templating.py +0 -0
  191. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/utilities/text.py +0 -0
  192. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/utilities/timeout.py +0 -0
  193. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/utilities/urls.py +0 -0
  194. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/utilities/visualization.py +0 -0
  195. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/variables.py +0 -0
  196. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/workers/__init__.py +0 -0
  197. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/workers/base.py +0 -0
  198. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/workers/block.py +0 -0
  199. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/workers/cloud.py +0 -0
  200. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/workers/process.py +0 -0
  201. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/workers/server.py +0 -0
  202. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect/workers/utilities.py +0 -0
  203. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect_client.egg-info/dependency_links.txt +0 -0
  204. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/src/prefect_client.egg-info/top_level.txt +0 -0
  205. {prefect-client-3.0.0rc12 → prefect-client-3.0.0rc14}/versioneer.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: prefect-client
3
- Version: 3.0.0rc12
3
+ Version: 3.0.0rc14
4
4
  Summary: Workflow orchestration and management.
5
5
  Home-page: https://www.prefect.io
6
6
  Author: Prefect Technologies, Inc.
@@ -19,6 +19,7 @@ orjson >= 3.7, < 4.0
19
19
  packaging >= 21.3, < 24.3
20
20
  pathspec >= 0.8.0
21
21
  pendulum >= 3.0.0, <4
22
+ prometheus-client >= 0.20.0
22
23
  pydantic >= 2.7, < 3.0.0
23
24
  pydantic_core >= 2.12.0, < 3.0.0
24
25
  pydantic_extra_types >= 2.8.2, < 3.0.0
@@ -2,6 +2,7 @@ import hashlib
2
2
  import html
3
3
  import inspect
4
4
  import sys
5
+ import uuid
5
6
  import warnings
6
7
  from abc import ABC
7
8
  from functools import partial
@@ -790,6 +791,33 @@ class Block(BaseModel, ABC):
790
791
 
791
792
  return block_document, block_document_name
792
793
 
794
+ @classmethod
795
+ @sync_compatible
796
+ @inject_client
797
+ async def _get_block_document_by_id(
798
+ cls,
799
+ block_document_id: Union[str, uuid.UUID],
800
+ client: Optional["PrefectClient"] = None,
801
+ ):
802
+ if isinstance(block_document_id, str):
803
+ try:
804
+ block_document_id = UUID(block_document_id)
805
+ except ValueError:
806
+ raise ValueError(
807
+ f"Block document ID {block_document_id!r} is not a valid UUID"
808
+ )
809
+
810
+ try:
811
+ block_document = await client.read_block_document(
812
+ block_document_id=block_document_id
813
+ )
814
+ except prefect.exceptions.ObjectNotFound:
815
+ raise ValueError(
816
+ f"Unable to find block document with ID {block_document_id!r}"
817
+ )
818
+
819
+ return block_document, block_document.name
820
+
793
821
  @classmethod
794
822
  @sync_compatible
795
823
  @inject_client
@@ -874,8 +902,108 @@ class Block(BaseModel, ABC):
874
902
  loaded_block.save("my-custom-message", overwrite=True)
875
903
  ```
876
904
  """
877
- block_document, block_document_name = await cls._get_block_document(name)
905
+ block_document, block_document_name = await cls._get_block_document(
906
+ name, client=client
907
+ )
908
+
909
+ return cls._load_from_block_document(block_document, validate=validate)
910
+
911
+ @classmethod
912
+ @sync_compatible
913
+ @inject_client
914
+ async def load_from_ref(
915
+ cls,
916
+ ref: Union[str, UUID, Dict[str, Any]],
917
+ validate: bool = True,
918
+ client: Optional["PrefectClient"] = None,
919
+ ) -> "Self":
920
+ """
921
+ Retrieves data from the block document by given reference for the block type
922
+ that corresponds with the current class and returns an instantiated version of
923
+ the current class with the data stored in the block document.
924
+
925
+ Provided reference can be a block document ID, or a reference data in dictionary format.
926
+ Supported dictionary reference formats are:
927
+ - {"block_document_id": <block_document_id>}
928
+ - {"block_document_slug": <block_document_slug>}
929
+
930
+ If a block document for a given block type is saved with a different schema
931
+ than the current class calling `load`, a warning will be raised.
878
932
 
933
+ If the current class schema is a subset of the block document schema, the block
934
+ can be loaded as normal using the default `validate = True`.
935
+
936
+ If the current class schema is a superset of the block document schema, `load`
937
+ must be called with `validate` set to False to prevent a validation error. In
938
+ this case, the block attributes will default to `None` and must be set manually
939
+ and saved to a new block document before the block can be used as expected.
940
+
941
+ Args:
942
+ ref: The reference to the block document. This can be a block document ID,
943
+ or one of supported dictionary reference formats.
944
+ validate: If False, the block document will be loaded without Pydantic
945
+ validating the block schema. This is useful if the block schema has
946
+ changed client-side since the block document referred to by `name` was saved.
947
+ client: The client to use to load the block document. If not provided, the
948
+ default client will be injected.
949
+
950
+ Raises:
951
+ ValueError: If invalid reference format is provided.
952
+ ValueError: If the requested block document is not found.
953
+
954
+ Returns:
955
+ An instance of the current class hydrated with the data stored in the
956
+ block document with the specified name.
957
+
958
+ """
959
+ block_document = None
960
+ if isinstance(ref, (str, UUID)):
961
+ block_document, _ = await cls._get_block_document_by_id(ref)
962
+ elif isinstance(ref, dict):
963
+ if block_document_id := ref.get("block_document_id"):
964
+ block_document, _ = await cls._get_block_document_by_id(
965
+ block_document_id
966
+ )
967
+ elif block_document_slug := ref.get("block_document_slug"):
968
+ block_document, _ = await cls._get_block_document(block_document_slug)
969
+
970
+ if not block_document:
971
+ raise ValueError(f"Invalid reference format {ref!r}.")
972
+
973
+ return cls._load_from_block_document(block_document, validate=validate)
974
+
975
+ @classmethod
976
+ def _load_from_block_document(
977
+ cls, block_document: BlockDocument, validate: bool = True
978
+ ) -> "Self":
979
+ """
980
+ Loads a block from a given block document.
981
+
982
+ If a block document for a given block type is saved with a different schema
983
+ than the current class calling `load`, a warning will be raised.
984
+
985
+ If the current class schema is a subset of the block document schema, the block
986
+ can be loaded as normal using the default `validate = True`.
987
+
988
+ If the current class schema is a superset of the block document schema, `load`
989
+ must be called with `validate` set to False to prevent a validation error. In
990
+ this case, the block attributes will default to `None` and must be set manually
991
+ and saved to a new block document before the block can be used as expected.
992
+
993
+ Args:
994
+ block_document: The block document used to instantiate a block.
995
+ validate: If False, the block document will be loaded without Pydantic
996
+ validating the block schema. This is useful if the block schema has
997
+ changed client-side since the block document referred to by `name` was saved.
998
+
999
+ Raises:
1000
+ ValueError: If the requested block document is not found.
1001
+
1002
+ Returns:
1003
+ An instance of the current class hydrated with the data stored in the
1004
+ block document with the specified name.
1005
+
1006
+ """
879
1007
  try:
880
1008
  return cls._from_block_document(block_document)
881
1009
  except ValidationError as e:
@@ -883,18 +1011,18 @@ class Block(BaseModel, ABC):
883
1011
  missing_fields = tuple(err["loc"][0] for err in e.errors())
884
1012
  missing_block_data = {field: None for field in missing_fields}
885
1013
  warnings.warn(
886
- f"Could not fully load {block_document_name!r} of block type"
1014
+ f"Could not fully load {block_document.name!r} of block type"
887
1015
  f" {cls.get_block_type_slug()!r} - this is likely because one or more"
888
1016
  " required fields were added to the schema for"
889
1017
  f" {cls.__name__!r} that did not exist on the class when this block"
890
1018
  " was last saved. Please specify values for new field(s):"
891
1019
  f" {listrepr(missing_fields)}, then run"
892
- f' `{cls.__name__}.save("{block_document_name}", overwrite=True)`,'
1020
+ f' `{cls.__name__}.save("{block_document.name}", overwrite=True)`,'
893
1021
  " and load this block again before attempting to use it."
894
1022
  )
895
1023
  return cls.model_construct(**block_document.data, **missing_block_data)
896
1024
  raise RuntimeError(
897
- f"Unable to load {block_document_name!r} of block type"
1025
+ f"Unable to load {block_document.name!r} of block type"
898
1026
  f" {cls.get_block_type_slug()!r} due to failed validation. To load without"
899
1027
  " validation, try loading again with `validate=False`."
900
1028
  ) from e
@@ -129,14 +129,37 @@ class MicrosoftTeamsWebhook(AppriseNotificationBlock):
129
129
  _documentation_url = "https://docs.prefect.io/api-ref/prefect/blocks/notifications/#prefect.blocks.notifications.MicrosoftTeamsWebhook"
130
130
 
131
131
  url: SecretStr = Field(
132
- ...,
132
+ default=...,
133
133
  title="Webhook URL",
134
- description="The Teams incoming webhook URL used to send notifications.",
134
+ description="The Microsoft Power Automate (Workflows) URL used to send notifications to Teams.",
135
135
  examples=[
136
- "https://your-org.webhook.office.com/webhookb2/XXX/IncomingWebhook/YYY/ZZZ"
136
+ "https://prod-NO.LOCATION.logic.azure.com:443/workflows/WFID/triggers/manual/paths/invoke?api-version=2016-06-01&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=SIGNATURE"
137
137
  ],
138
138
  )
139
139
 
140
+ include_image: bool = Field(
141
+ default=True,
142
+ description="Include an image with the notification.",
143
+ )
144
+
145
+ wrap: bool = Field(
146
+ default=True,
147
+ description="Wrap the notification text.",
148
+ )
149
+
150
+ def block_initialization(self) -> None:
151
+ """see https://github.com/caronc/apprise/pull/1172"""
152
+ from apprise.plugins.workflows import NotifyWorkflows
153
+
154
+ if not (
155
+ parsed_url := NotifyWorkflows.parse_native_url(self.url.get_secret_value())
156
+ ):
157
+ raise ValueError("Invalid Microsoft Teams Workflow URL provided.")
158
+
159
+ parsed_url |= {"include_image": self.include_image, "wrap": self.wrap}
160
+
161
+ self._start_apprise_client(SecretStr(NotifyWorkflows(**parsed_url).url()))
162
+
140
163
 
141
164
  class PagerDutyWebHook(AbstractAppriseNotificationBlock):
142
165
  """
@@ -26,7 +26,6 @@ import httpx
26
26
  from asgi_lifespan import LifespanManager
27
27
  from httpx import HTTPStatusError, Request, Response
28
28
  from starlette import status
29
- from starlette.testclient import TestClient
30
29
  from typing_extensions import Self
31
30
 
32
31
  import prefect
@@ -35,10 +34,14 @@ from prefect.client.schemas.objects import CsrfToken
35
34
  from prefect.exceptions import PrefectHTTPStatusError
36
35
  from prefect.logging import get_logger
37
36
  from prefect.settings import (
37
+ PREFECT_API_URL,
38
38
  PREFECT_CLIENT_MAX_RETRIES,
39
39
  PREFECT_CLIENT_RETRY_EXTRA_CODES,
40
40
  PREFECT_CLIENT_RETRY_JITTER_FACTOR,
41
+ PREFECT_CLOUD_API_URL,
42
+ PREFECT_SERVER_ALLOW_EPHEMERAL_MODE,
41
43
  )
44
+ from prefect.utilities.collections import AutoEnum
42
45
  from prefect.utilities.math import bounded_poisson_interval, clamped_poisson_interval
43
46
 
44
47
  # Datastores for lifespan management, keys should be a tuple of thread and app
@@ -612,28 +615,31 @@ class PrefectHttpxSyncClient(httpx.Client):
612
615
  request.headers["Prefect-Csrf-Client"] = str(self.csrf_client_id)
613
616
 
614
617
 
615
- class PrefectHttpxSyncEphemeralClient(TestClient, PrefectHttpxSyncClient):
616
- """
617
- This client is a synchronous httpx client that can be used to talk directly
618
- to an ASGI app, such as an ephemeral Prefect API.
619
-
620
- It is a subclass of both Starlette's `TestClient` and Prefect's
621
- `PrefectHttpxSyncClient`, so it combines the synchronous testing
622
- capabilities of `TestClient` with the Prefect-specific behaviors of
623
- `PrefectHttpxSyncClient`.
624
- """
618
+ class ServerType(AutoEnum):
619
+ EPHEMERAL = AutoEnum.auto()
620
+ SERVER = AutoEnum.auto()
621
+ CLOUD = AutoEnum.auto()
622
+ UNCONFIGURED = AutoEnum.auto()
625
623
 
626
- def __init__(
627
- self,
628
- *args,
629
- # override TestClient default
630
- raise_server_exceptions=False,
631
- **kwargs,
632
- ):
633
- super().__init__(
634
- *args,
635
- raise_server_exceptions=raise_server_exceptions,
636
- **kwargs,
637
- )
638
624
 
639
- pass
625
+ def determine_server_type() -> ServerType:
626
+ """
627
+ Determine the server type based on the current settings.
628
+
629
+ Returns:
630
+ - `ServerType.EPHEMERAL` if the ephemeral server is enabled
631
+ - `ServerType.SERVER` if a API URL is configured and it is not a cloud URL
632
+ - `ServerType.CLOUD` if an API URL is configured and it is a cloud URL
633
+ - `ServerType.UNCONFIGURED` if no API URL is configured and ephemeral mode is
634
+ not enabled
635
+ """
636
+ api_url = PREFECT_API_URL.value()
637
+ if api_url is None:
638
+ if PREFECT_SERVER_ALLOW_EPHEMERAL_MODE.value():
639
+ return ServerType.EPHEMERAL
640
+ else:
641
+ return ServerType.UNCONFIGURED
642
+ if api_url.startswith(PREFECT_CLOUD_API_URL.value()):
643
+ return ServerType.CLOUD
644
+ else:
645
+ return ServerType.SERVER
@@ -132,9 +132,9 @@ from prefect.settings import (
132
132
  PREFECT_API_URL,
133
133
  PREFECT_CLIENT_CSRF_SUPPORT_ENABLED,
134
134
  PREFECT_CLOUD_API_URL,
135
+ PREFECT_SERVER_ALLOW_EPHEMERAL_MODE,
135
136
  PREFECT_UNIT_TEST_MODE,
136
137
  )
137
- from prefect.utilities.collections import AutoEnum
138
138
 
139
139
  if TYPE_CHECKING:
140
140
  from prefect.flows import Flow as FlowObject
@@ -144,7 +144,7 @@ from prefect.client.base import (
144
144
  ASGIApp,
145
145
  PrefectHttpxAsyncClient,
146
146
  PrefectHttpxSyncClient,
147
- PrefectHttpxSyncEphemeralClient,
147
+ ServerType,
148
148
  app_lifespan_context,
149
149
  )
150
150
 
@@ -152,12 +152,6 @@ P = ParamSpec("P")
152
152
  R = TypeVar("R")
153
153
 
154
154
 
155
- class ServerType(AutoEnum):
156
- EPHEMERAL = AutoEnum.auto()
157
- SERVER = AutoEnum.auto()
158
- CLOUD = AutoEnum.auto()
159
-
160
-
161
155
  @overload
162
156
  def get_client(
163
157
  httpx_settings: Optional[Dict[str, Any]] = None, sync_client: Literal[False] = False
@@ -194,8 +188,6 @@ def get_client(
194
188
  """
195
189
  import prefect.context
196
190
 
197
- settings_ctx = prefect.context.get_settings_context()
198
-
199
191
  # try to load clients from a client context, if possible
200
192
  # only load clients that match the provided config / loop
201
193
  try:
@@ -203,40 +195,50 @@ def get_client(
203
195
  except RuntimeError:
204
196
  loop = None
205
197
 
206
- if client_ctx := prefect.context.ClientContext.get():
207
- if (
208
- sync_client
209
- and client_ctx.sync_client
210
- and client_ctx._httpx_settings == httpx_settings
211
- ):
212
- return client_ctx.sync_client
213
- elif (
214
- not sync_client
215
- and client_ctx.async_client
216
- and client_ctx._httpx_settings == httpx_settings
217
- and loop in (client_ctx.async_client._loop, None)
218
- ):
219
- return client_ctx.async_client
198
+ if sync_client:
199
+ if client_ctx := prefect.context.SyncClientContext.get():
200
+ if client_ctx.client and client_ctx._httpx_settings == httpx_settings:
201
+ return client_ctx.client
202
+ else:
203
+ if client_ctx := prefect.context.AsyncClientContext.get():
204
+ if (
205
+ client_ctx.client
206
+ and client_ctx._httpx_settings == httpx_settings
207
+ and loop in (client_ctx.client._loop, None)
208
+ ):
209
+ return client_ctx.client
220
210
 
221
211
  api = PREFECT_API_URL.value()
212
+ server_type = None
222
213
 
223
- if not api:
214
+ if not api and PREFECT_SERVER_ALLOW_EPHEMERAL_MODE:
224
215
  # create an ephemeral API if none was provided
225
- from prefect.server.api.server import create_app
216
+ from prefect.server.api.server import SubprocessASGIServer
217
+
218
+ server = SubprocessASGIServer()
219
+ server.start()
220
+ assert server.server_process is not None, "Server process did not start"
226
221
 
227
- api = create_app(settings_ctx.settings, ephemeral=True)
222
+ api = server.api_url
223
+ server_type = ServerType.EPHEMERAL
224
+ elif not api and not PREFECT_SERVER_ALLOW_EPHEMERAL_MODE:
225
+ raise ValueError(
226
+ "No Prefect API URL provided. Please set PREFECT_API_URL to the address of a running Prefect server."
227
+ )
228
228
 
229
229
  if sync_client:
230
230
  return SyncPrefectClient(
231
231
  api,
232
232
  api_key=PREFECT_API_KEY.value(),
233
233
  httpx_settings=httpx_settings,
234
+ server_type=server_type,
234
235
  )
235
236
  else:
236
237
  return PrefectClient(
237
238
  api,
238
239
  api_key=PREFECT_API_KEY.value(),
239
240
  httpx_settings=httpx_settings,
241
+ server_type=server_type,
240
242
  )
241
243
 
242
244
 
@@ -273,6 +275,7 @@ class PrefectClient:
273
275
  api_key: Optional[str] = None,
274
276
  api_version: Optional[str] = None,
275
277
  httpx_settings: Optional[Dict[str, Any]] = None,
278
+ server_type: Optional[ServerType] = None,
276
279
  ) -> None:
277
280
  httpx_settings = httpx_settings.copy() if httpx_settings else {}
278
281
  httpx_settings.setdefault("headers", {})
@@ -335,11 +338,14 @@ class PrefectClient:
335
338
  # client will use a standard HTTP/1.1 connection instead.
336
339
  httpx_settings.setdefault("http2", PREFECT_API_ENABLE_HTTP2.value())
337
340
 
338
- self.server_type = (
339
- ServerType.CLOUD
340
- if api.startswith(PREFECT_CLOUD_API_URL.value())
341
- else ServerType.SERVER
342
- )
341
+ if server_type:
342
+ self.server_type = server_type
343
+ else:
344
+ self.server_type = (
345
+ ServerType.CLOUD
346
+ if api.startswith(PREFECT_CLOUD_API_URL.value())
347
+ else ServerType.SERVER
348
+ )
343
349
 
344
350
  # Connect to an in-process application
345
351
  elif isinstance(api, ASGIApp):
@@ -3012,16 +3018,34 @@ class PrefectClient:
3012
3018
  return response.json()
3013
3019
 
3014
3020
  async def increment_concurrency_slots(
3015
- self, names: List[str], slots: int, mode: str
3021
+ self, names: List[str], slots: int, mode: str, create_if_missing: Optional[bool]
3016
3022
  ) -> httpx.Response:
3017
3023
  return await self._client.post(
3018
3024
  "/v2/concurrency_limits/increment",
3019
- json={"names": names, "slots": slots, "mode": mode},
3025
+ json={
3026
+ "names": names,
3027
+ "slots": slots,
3028
+ "mode": mode,
3029
+ "create_if_missing": create_if_missing,
3030
+ },
3020
3031
  )
3021
3032
 
3022
3033
  async def release_concurrency_slots(
3023
3034
  self, names: List[str], slots: int, occupancy_seconds: float
3024
3035
  ) -> httpx.Response:
3036
+ """
3037
+ Release concurrency slots for the specified limits.
3038
+
3039
+ Args:
3040
+ names (List[str]): A list of limit names for which to release slots.
3041
+ slots (int): The number of concurrency slots to release.
3042
+ occupancy_seconds (float): The duration in seconds that the slots
3043
+ were occupied.
3044
+
3045
+ Returns:
3046
+ httpx.Response: The HTTP response from the server.
3047
+ """
3048
+
3025
3049
  return await self._client.post(
3026
3050
  "/v2/concurrency_limits/decrement",
3027
3051
  json={
@@ -3370,6 +3394,7 @@ class SyncPrefectClient:
3370
3394
  api_key: Optional[str] = None,
3371
3395
  api_version: Optional[str] = None,
3372
3396
  httpx_settings: Optional[Dict[str, Any]] = None,
3397
+ server_type: Optional[ServerType] = None,
3373
3398
  ) -> None:
3374
3399
  httpx_settings = httpx_settings.copy() if httpx_settings else {}
3375
3400
  httpx_settings.setdefault("headers", {})
@@ -3428,11 +3453,14 @@ class SyncPrefectClient:
3428
3453
  # client will use a standard HTTP/1.1 connection instead.
3429
3454
  httpx_settings.setdefault("http2", PREFECT_API_ENABLE_HTTP2.value())
3430
3455
 
3431
- self.server_type = (
3432
- ServerType.CLOUD
3433
- if api.startswith(PREFECT_CLOUD_API_URL.value())
3434
- else ServerType.SERVER
3435
- )
3456
+ if server_type:
3457
+ self.server_type = server_type
3458
+ else:
3459
+ self.server_type = (
3460
+ ServerType.CLOUD
3461
+ if api.startswith(PREFECT_CLOUD_API_URL.value())
3462
+ else ServerType.SERVER
3463
+ )
3436
3464
 
3437
3465
  # Connect to an in-process application
3438
3466
  elif isinstance(api, ASGIApp):
@@ -3464,14 +3492,9 @@ class SyncPrefectClient:
3464
3492
  and PREFECT_CLIENT_CSRF_SUPPORT_ENABLED.value()
3465
3493
  )
3466
3494
 
3467
- if self.server_type == ServerType.EPHEMERAL:
3468
- self._client = PrefectHttpxSyncEphemeralClient(
3469
- api, base_url="http://ephemeral-prefect/api"
3470
- )
3471
- else:
3472
- self._client = PrefectHttpxSyncClient(
3473
- **httpx_settings, enable_csrf_support=enable_csrf_support
3474
- )
3495
+ self._client = PrefectHttpxSyncClient(
3496
+ **httpx_settings, enable_csrf_support=enable_csrf_support
3497
+ )
3475
3498
 
3476
3499
  # See https://www.python-httpx.org/advanced/#custom-transports
3477
3500
  #
@@ -4046,6 +4069,33 @@ class SyncPrefectClient:
4046
4069
  raise
4047
4070
  return DeploymentResponse.model_validate(response.json())
4048
4071
 
4072
+ def read_deployment_by_name(
4073
+ self,
4074
+ name: str,
4075
+ ) -> DeploymentResponse:
4076
+ """
4077
+ Query the Prefect API for a deployment by name.
4078
+
4079
+ Args:
4080
+ name: A deployed flow's name: <FLOW_NAME>/<DEPLOYMENT_NAME>
4081
+
4082
+ Raises:
4083
+ prefect.exceptions.ObjectNotFound: If request returns 404
4084
+ httpx.RequestError: If request fails
4085
+
4086
+ Returns:
4087
+ a Deployment model representation of the deployment
4088
+ """
4089
+ try:
4090
+ response = self._client.get(f"/deployments/name/{name}")
4091
+ except httpx.HTTPStatusError as e:
4092
+ if e.response.status_code == status.HTTP_404_NOT_FOUND:
4093
+ raise prefect.exceptions.ObjectNotFound(http_exc=e) from e
4094
+ else:
4095
+ raise
4096
+
4097
+ return DeploymentResponse.model_validate(response.json())
4098
+
4049
4099
  def create_artifact(
4050
4100
  self,
4051
4101
  artifact: ArtifactCreate,
@@ -4065,3 +4115,27 @@ class SyncPrefectClient:
4065
4115
  )
4066
4116
 
4067
4117
  return Artifact.model_validate(response.json())
4118
+
4119
+ def release_concurrency_slots(
4120
+ self, names: List[str], slots: int, occupancy_seconds: float
4121
+ ) -> httpx.Response:
4122
+ """
4123
+ Release concurrency slots for the specified limits.
4124
+
4125
+ Args:
4126
+ names (List[str]): A list of limit names for which to release slots.
4127
+ slots (int): The number of concurrency slots to release.
4128
+ occupancy_seconds (float): The duration in seconds that the slots
4129
+ were occupied.
4130
+
4131
+ Returns:
4132
+ httpx.Response: The HTTP response from the server.
4133
+ """
4134
+ return self._client.post(
4135
+ "/v2/concurrency_limits/decrement",
4136
+ json={
4137
+ "names": names,
4138
+ "slots": slots,
4139
+ "occupancy_seconds": occupancy_seconds,
4140
+ },
4141
+ )
@@ -42,14 +42,14 @@ def get_or_create_client(
42
42
  if client is not None:
43
43
  return client, True
44
44
  from prefect._internal.concurrency.event_loop import get_running_loop
45
- from prefect.context import ClientContext, FlowRunContext, TaskRunContext
45
+ from prefect.context import AsyncClientContext, FlowRunContext, TaskRunContext
46
46
 
47
- client_context = ClientContext.get()
47
+ async_client_context = AsyncClientContext.get()
48
48
  flow_run_context = FlowRunContext.get()
49
49
  task_run_context = TaskRunContext.get()
50
50
 
51
- if client_context and client_context.async_client._loop == get_running_loop():
52
- return client_context.async_client, True
51
+ if async_client_context and async_client_context.client._loop == get_running_loop():
52
+ return async_client_context.client, True
53
53
  elif (
54
54
  flow_run_context
55
55
  and getattr(flow_run_context.client, "_loop", None) == get_running_loop()