prefect-client 3.1.2__tar.gz → 3.1.4__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 (255) hide show
  1. {prefect-client-3.1.2/src/prefect_client.egg-info → prefect-client-3.1.4}/PKG-INFO +1 -1
  2. {prefect-client-3.1.2 → prefect-client-3.1.4}/requirements-client.txt +2 -1
  3. {prefect-client-3.1.2 → prefect-client-3.1.4}/requirements.txt +0 -1
  4. prefect-client-3.1.4/src/prefect/_internal/compatibility/async_dispatch.py +63 -0
  5. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/_internal/schemas/bases.py +4 -1
  6. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/_version.py +3 -3
  7. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/blocks/notifications.py +1 -0
  8. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/cache_policies.py +13 -2
  9. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/client/cloud.py +1 -1
  10. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/client/orchestration.py +7 -7
  11. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/client/schemas/objects.py +9 -26
  12. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/deployments/runner.py +2 -1
  13. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/events/filters.py +13 -9
  14. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/exceptions.py +4 -0
  15. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/flow_engine.py +56 -1
  16. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/logging/handlers.py +5 -4
  17. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/settings/models/experiments.py +0 -5
  18. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/telemetry/processors.py +2 -2
  19. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/types/__init__.py +18 -1
  20. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/utilities/filesystem.py +35 -8
  21. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/utilities/hashing.py +28 -7
  22. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/utilities/urls.py +2 -2
  23. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/workers/base.py +30 -20
  24. {prefect-client-3.1.2 → prefect-client-3.1.4/src/prefect_client.egg-info}/PKG-INFO +1 -1
  25. prefect-client-3.1.4/src/prefect_client.egg-info/dependency_links.txt +1 -0
  26. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect_client.egg-info/requires.txt +2 -1
  27. prefect-client-3.1.2/src/prefect/_internal/compatibility/async_dispatch.py +0 -73
  28. prefect-client-3.1.2/src/prefect/utilities/__init__.py +0 -0
  29. {prefect-client-3.1.2 → prefect-client-3.1.4}/LICENSE +0 -0
  30. {prefect-client-3.1.2 → prefect-client-3.1.4}/MANIFEST.in +0 -0
  31. {prefect-client-3.1.2 → prefect-client-3.1.4}/README.md +0 -0
  32. {prefect-client-3.1.2 → prefect-client-3.1.4}/requirements-dev.txt +0 -0
  33. {prefect-client-3.1.2 → prefect-client-3.1.4}/setup.cfg +0 -0
  34. {prefect-client-3.1.2 → prefect-client-3.1.4}/setup.py +0 -0
  35. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/.prefectignore +0 -0
  36. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/__init__.py +0 -0
  37. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/_internal/__init__.py +0 -0
  38. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/_internal/_logging.py +0 -0
  39. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/_internal/compatibility/__init__.py +0 -0
  40. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/_internal/compatibility/deprecated.py +0 -0
  41. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/_internal/compatibility/migration.py +0 -0
  42. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/_internal/concurrency/__init__.py +0 -0
  43. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/_internal/concurrency/api.py +0 -0
  44. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/_internal/concurrency/calls.py +0 -0
  45. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/_internal/concurrency/cancellation.py +0 -0
  46. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/_internal/concurrency/event_loop.py +0 -0
  47. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/_internal/concurrency/inspection.py +0 -0
  48. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/_internal/concurrency/primitives.py +0 -0
  49. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/_internal/concurrency/services.py +0 -0
  50. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/_internal/concurrency/threads.py +0 -0
  51. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/_internal/concurrency/waiters.py +0 -0
  52. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/_internal/integrations.py +0 -0
  53. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/_internal/pydantic/__init__.py +0 -0
  54. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/_internal/pydantic/annotations/__init__.py +0 -0
  55. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/_internal/pydantic/annotations/pendulum.py +0 -0
  56. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/_internal/pydantic/schemas.py +0 -0
  57. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/_internal/pydantic/v1_schema.py +0 -0
  58. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/_internal/pydantic/v2_schema.py +0 -0
  59. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/_internal/pydantic/v2_validated_func.py +0 -0
  60. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/_internal/pytz.py +0 -0
  61. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/_internal/retries.py +0 -0
  62. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/_internal/schemas/__init__.py +0 -0
  63. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/_internal/schemas/fields.py +0 -0
  64. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/_internal/schemas/serializers.py +0 -0
  65. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/_internal/schemas/validators.py +0 -0
  66. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/agent.py +0 -0
  67. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/artifacts.py +0 -0
  68. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/automations.py +0 -0
  69. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/blocks/__init__.py +0 -0
  70. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/blocks/abstract.py +0 -0
  71. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/blocks/core.py +0 -0
  72. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/blocks/fields.py +0 -0
  73. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/blocks/redis.py +0 -0
  74. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/blocks/system.py +0 -0
  75. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/blocks/webhook.py +0 -0
  76. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/client/__init__.py +0 -0
  77. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/client/base.py +0 -0
  78. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/client/collections.py +0 -0
  79. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/client/constants.py +0 -0
  80. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/client/schemas/__init__.py +0 -0
  81. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/client/schemas/actions.py +0 -0
  82. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/client/schemas/filters.py +0 -0
  83. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/client/schemas/responses.py +0 -0
  84. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/client/schemas/schedules.py +0 -0
  85. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/client/schemas/sorting.py +0 -0
  86. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/client/subscriptions.py +0 -0
  87. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/client/types/__init__.py +0 -0
  88. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/client/types/flexible_schedule_list.py +0 -0
  89. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/client/utilities.py +0 -0
  90. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/concurrency/__init__.py +0 -0
  91. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/concurrency/asyncio.py +0 -0
  92. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/concurrency/context.py +0 -0
  93. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/concurrency/events.py +0 -0
  94. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/concurrency/services.py +0 -0
  95. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/concurrency/sync.py +0 -0
  96. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/concurrency/v1/__init__.py +0 -0
  97. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/concurrency/v1/asyncio.py +0 -0
  98. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/concurrency/v1/context.py +0 -0
  99. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/concurrency/v1/events.py +0 -0
  100. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/concurrency/v1/services.py +0 -0
  101. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/concurrency/v1/sync.py +0 -0
  102. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/context.py +0 -0
  103. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/deployments/__init__.py +0 -0
  104. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/deployments/base.py +0 -0
  105. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/deployments/deployments.py +0 -0
  106. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/deployments/flow_runs.py +0 -0
  107. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/deployments/schedules.py +0 -0
  108. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/deployments/steps/__init__.py +0 -0
  109. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/deployments/steps/core.py +0 -0
  110. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/deployments/steps/pull.py +0 -0
  111. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/deployments/steps/utility.py +0 -0
  112. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/docker/__init__.py +0 -0
  113. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/docker/docker_image.py +0 -0
  114. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/engine.py +0 -0
  115. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/events/__init__.py +0 -0
  116. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/events/actions.py +0 -0
  117. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/events/cli/__init__.py +0 -0
  118. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/events/cli/automations.py +0 -0
  119. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/events/clients.py +0 -0
  120. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/events/related.py +0 -0
  121. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/events/schemas/__init__.py +0 -0
  122. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/events/schemas/automations.py +0 -0
  123. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/events/schemas/deployment_triggers.py +0 -0
  124. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/events/schemas/events.py +0 -0
  125. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/events/schemas/labelling.py +0 -0
  126. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/events/utilities.py +0 -0
  127. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/events/worker.py +0 -0
  128. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/filesystems.py +0 -0
  129. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/flow_runs.py +0 -0
  130. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/flows.py +0 -0
  131. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/futures.py +0 -0
  132. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/infrastructure/__init__.py +0 -0
  133. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/infrastructure/base.py +0 -0
  134. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/infrastructure/provisioners/__init__.py +0 -0
  135. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/infrastructure/provisioners/cloud_run.py +0 -0
  136. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/infrastructure/provisioners/container_instance.py +0 -0
  137. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/infrastructure/provisioners/ecs.py +0 -0
  138. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/infrastructure/provisioners/modal.py +0 -0
  139. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/input/__init__.py +0 -0
  140. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/input/actions.py +0 -0
  141. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/input/run_input.py +0 -0
  142. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/locking/__init__.py +0 -0
  143. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/locking/filesystem.py +0 -0
  144. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/locking/memory.py +0 -0
  145. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/locking/protocol.py +0 -0
  146. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/logging/__init__.py +0 -0
  147. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/logging/configuration.py +0 -0
  148. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/logging/filters.py +0 -0
  149. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/logging/formatters.py +0 -0
  150. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/logging/highlighters.py +0 -0
  151. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/logging/loggers.py +0 -0
  152. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/logging/logging.yml +0 -0
  153. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/main.py +0 -0
  154. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/plugins.py +0 -0
  155. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/py.typed +0 -0
  156. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/records/__init__.py +0 -0
  157. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/records/base.py +0 -0
  158. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/records/filesystem.py +0 -0
  159. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/records/memory.py +0 -0
  160. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/records/result_store.py +0 -0
  161. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/results.py +0 -0
  162. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/runner/__init__.py +0 -0
  163. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/runner/runner.py +0 -0
  164. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/runner/server.py +0 -0
  165. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/runner/storage.py +0 -0
  166. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/runner/submit.py +0 -0
  167. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/runner/utils.py +0 -0
  168. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/runtime/__init__.py +0 -0
  169. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/runtime/deployment.py +0 -0
  170. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/runtime/flow_run.py +0 -0
  171. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/runtime/task_run.py +0 -0
  172. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/serializers.py +0 -0
  173. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/server/api/collections_data/views/aggregate-worker-metadata.json +0 -0
  174. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/server/api/static/prefect-logo-mark-gradient.png +0 -0
  175. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/settings/__init__.py +0 -0
  176. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/settings/base.py +0 -0
  177. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/settings/constants.py +0 -0
  178. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/settings/context.py +0 -0
  179. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/settings/legacy.py +0 -0
  180. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/settings/models/__init__.py +0 -0
  181. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/settings/models/api.py +0 -0
  182. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/settings/models/cli.py +0 -0
  183. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/settings/models/client.py +0 -0
  184. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/settings/models/cloud.py +0 -0
  185. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/settings/models/deployments.py +0 -0
  186. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/settings/models/flows.py +0 -0
  187. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/settings/models/internal.py +0 -0
  188. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/settings/models/logging.py +0 -0
  189. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/settings/models/results.py +0 -0
  190. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/settings/models/root.py +0 -0
  191. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/settings/models/runner.py +0 -0
  192. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/settings/models/server/__init__.py +0 -0
  193. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/settings/models/server/api.py +0 -0
  194. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/settings/models/server/database.py +0 -0
  195. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/settings/models/server/deployments.py +0 -0
  196. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/settings/models/server/ephemeral.py +0 -0
  197. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/settings/models/server/events.py +0 -0
  198. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/settings/models/server/flow_run_graph.py +0 -0
  199. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/settings/models/server/root.py +0 -0
  200. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/settings/models/server/services.py +0 -0
  201. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/settings/models/server/tasks.py +0 -0
  202. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/settings/models/server/ui.py +0 -0
  203. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/settings/models/tasks.py +0 -0
  204. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/settings/models/testing.py +0 -0
  205. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/settings/models/worker.py +0 -0
  206. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/settings/profiles.py +0 -0
  207. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/settings/profiles.toml +0 -0
  208. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/settings/sources.py +0 -0
  209. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/states.py +0 -0
  210. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/task_engine.py +0 -0
  211. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/task_runners.py +0 -0
  212. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/task_runs.py +0 -0
  213. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/task_worker.py +0 -0
  214. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/tasks.py +0 -0
  215. /prefect-client-3.1.2/src/prefect_client.egg-info/dependency_links.txt → /prefect-client-3.1.4/src/prefect/telemetry/__init__.py +0 -0
  216. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/telemetry/bootstrap.py +0 -0
  217. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/telemetry/instrumentation.py +0 -0
  218. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/telemetry/logging.py +0 -0
  219. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/transactions.py +0 -0
  220. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/types/entrypoint.py +0 -0
  221. {prefect-client-3.1.2/src/prefect/telemetry → prefect-client-3.1.4/src/prefect/utilities}/__init__.py +0 -0
  222. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/utilities/annotations.py +0 -0
  223. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/utilities/asyncutils.py +0 -0
  224. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/utilities/callables.py +0 -0
  225. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/utilities/collections.py +0 -0
  226. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/utilities/compat.py +0 -0
  227. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/utilities/context.py +0 -0
  228. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/utilities/dispatch.py +0 -0
  229. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/utilities/dockerutils.py +0 -0
  230. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/utilities/engine.py +0 -0
  231. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/utilities/importtools.py +0 -0
  232. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/utilities/math.py +0 -0
  233. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/utilities/names.py +0 -0
  234. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/utilities/processutils.py +0 -0
  235. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/utilities/pydantic.py +0 -0
  236. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/utilities/render_swagger.py +0 -0
  237. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/utilities/schema_tools/__init__.py +0 -0
  238. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/utilities/schema_tools/hydration.py +0 -0
  239. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/utilities/schema_tools/validation.py +0 -0
  240. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/utilities/services.py +0 -0
  241. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/utilities/slugify.py +0 -0
  242. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/utilities/templating.py +0 -0
  243. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/utilities/text.py +0 -0
  244. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/utilities/timeout.py +0 -0
  245. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/utilities/visualization.py +0 -0
  246. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/variables.py +0 -0
  247. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/workers/__init__.py +0 -0
  248. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/workers/block.py +0 -0
  249. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/workers/cloud.py +0 -0
  250. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/workers/process.py +0 -0
  251. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/workers/server.py +0 -0
  252. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect/workers/utilities.py +0 -0
  253. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect_client.egg-info/SOURCES.txt +0 -0
  254. {prefect-client-3.1.2 → prefect-client-3.1.4}/src/prefect_client.egg-info/top_level.txt +0 -0
  255. {prefect-client-3.1.2 → prefect-client-3.1.4}/versioneer.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: prefect-client
3
- Version: 3.1.2
3
+ Version: 3.1.4
4
4
  Summary: Workflow orchestration and management.
5
5
  Home-page: https://www.prefect.io
6
6
  Author: Prefect Technologies, Inc.
@@ -3,7 +3,7 @@ asgi-lifespan >= 1.0, < 3.0
3
3
  cachetools >= 5.3, < 6.0
4
4
  cloudpickle >= 2.0, < 4.0
5
5
  coolname >= 1.0.4, < 3.0.0
6
- croniter >= 1.0.12, < 5.0.0
6
+ croniter >= 1.0.12, < 6.0.0
7
7
  exceptiongroup >= 1.0.0
8
8
  fastapi >= 0.111.0, < 1.0.0
9
9
  fsspec >= 2022.5.0
@@ -14,6 +14,7 @@ httpx[http2] >= 0.23, != 0.23.2
14
14
  importlib_metadata >= 4.4; python_version < '3.10'
15
15
  jsonpatch >= 1.32, < 2.0
16
16
  jsonschema >= 4.0.0, < 5.0.0
17
+ opentelemetry-api >= 1.27.0, < 2.0.0
17
18
  orjson >= 3.7, < 4.0
18
19
  packaging >= 21.3, < 24.3
19
20
  pathspec >= 0.8.0
@@ -12,7 +12,6 @@ graphviz >= 0.20.1
12
12
  jinja2 >= 3.0.0, < 4.0.0
13
13
  jinja2-humanize-extension >= 0.4.0
14
14
  humanize >= 4.9.0, < 5.0.0
15
- opentelemetry-api >= 1.27.0, < 2.0.0
16
15
  pytz >= 2021.1, < 2025
17
16
  readchar >= 4.0.0, < 5.0.0
18
17
  sqlalchemy[asyncio] >= 2.0, < 3.0.0
@@ -0,0 +1,63 @@
1
+ import asyncio
2
+ import inspect
3
+ from functools import wraps
4
+ from typing import Any, Callable, Coroutine, Optional, TypeVar, Union
5
+
6
+ from typing_extensions import ParamSpec
7
+
8
+ from prefect.tasks import Task
9
+
10
+ R = TypeVar("R")
11
+ P = ParamSpec("P")
12
+
13
+
14
+ def is_in_async_context() -> bool:
15
+ """
16
+ Returns True if called from within an async context (coroutine or running event loop)
17
+ """
18
+ try:
19
+ asyncio.get_running_loop()
20
+ return True
21
+ except RuntimeError:
22
+ return False
23
+
24
+
25
+ def _is_acceptable_callable(obj: Union[Callable, Task]) -> bool:
26
+ if inspect.iscoroutinefunction(obj):
27
+ return True
28
+ if isinstance(obj, Task) and inspect.iscoroutinefunction(obj.fn):
29
+ return True
30
+ return False
31
+
32
+
33
+ def async_dispatch(
34
+ async_impl: Callable[P, Coroutine[Any, Any, R]],
35
+ ) -> Callable[[Callable[P, R]], Callable[P, Union[R, Coroutine[Any, Any, R]]]]:
36
+ """
37
+ Decorator that dispatches to either sync or async implementation based on context.
38
+
39
+ Args:
40
+ async_impl: The async implementation to dispatch to when in async context
41
+ """
42
+
43
+ def decorator(
44
+ sync_fn: Callable[P, R],
45
+ ) -> Callable[P, Union[R, Coroutine[Any, Any, R]]]:
46
+ if not _is_acceptable_callable(async_impl):
47
+ raise TypeError("async_impl must be an async function")
48
+
49
+ @wraps(sync_fn)
50
+ def wrapper(
51
+ *args: P.args,
52
+ _sync: Optional[bool] = None, # type: ignore
53
+ **kwargs: P.kwargs,
54
+ ) -> Union[R, Coroutine[Any, Any, R]]:
55
+ should_run_sync = _sync if _sync is not None else not is_in_async_context()
56
+
57
+ if should_run_sync:
58
+ return sync_fn(*args, **kwargs)
59
+ return async_impl(*args, **kwargs)
60
+
61
+ return wrapper # type: ignore
62
+
63
+ return decorator
@@ -84,9 +84,12 @@ class PrefectBaseModel(BaseModel):
84
84
  Returns:
85
85
  PrefectBaseModel: A new instance of the model with the reset fields.
86
86
  """
87
+ data = self.model_dump()
87
88
  return self.model_copy(
88
89
  update={
89
- field: self.model_fields[field].get_default(call_default_factory=True)
90
+ field: self.model_fields[field].get_default(
91
+ call_default_factory=True, validated_data=data
92
+ )
90
93
  for field in self._reset_fields
91
94
  }
92
95
  )
@@ -8,11 +8,11 @@ import json
8
8
 
9
9
  version_json = '''
10
10
  {
11
- "date": "2024-11-12T13:38:45-0800",
11
+ "date": "2024-11-20T19:37:35-0600",
12
12
  "dirty": true,
13
13
  "error": null,
14
- "full-revisionid": "02b99f0a756f0395e4292952dcb2d963fc839750",
15
- "version": "3.1.2"
14
+ "full-revisionid": "78ee41cb26058cc2dfba8aece6a2471ec5ea3675",
15
+ "version": "3.1.4"
16
16
  }
17
17
  ''' # END VERSION_JSON
18
18
 
@@ -494,6 +494,7 @@ class OpsgenieWebhook(AbstractAppriseNotificationBlock):
494
494
  entity=self.entity,
495
495
  batch=self.batch,
496
496
  tags=self.tags,
497
+ action="new",
497
498
  ).url()
498
499
  )
499
500
  self._start_apprise_client(url)
@@ -7,6 +7,7 @@ from typing import TYPE_CHECKING, Any, Callable, Dict, List, Literal, Optional,
7
7
  from typing_extensions import Self
8
8
 
9
9
  from prefect.context import TaskRunContext
10
+ from prefect.exceptions import HashError
10
11
  from prefect.utilities.hashing import hash_objects
11
12
 
12
13
  if TYPE_CHECKING:
@@ -223,7 +224,6 @@ class TaskSource(CachePolicy):
223
224
  lines = task_ctx.task.fn.__code__.co_code
224
225
  else:
225
226
  raise
226
-
227
227
  return hash_objects(lines, raise_on_failure=True)
228
228
 
229
229
 
@@ -293,7 +293,18 @@ class Inputs(CachePolicy):
293
293
  if key not in exclude:
294
294
  hashed_inputs[key] = val
295
295
 
296
- return hash_objects(hashed_inputs, raise_on_failure=True)
296
+ try:
297
+ return hash_objects(hashed_inputs, raise_on_failure=True)
298
+ except HashError as exc:
299
+ msg = (
300
+ f"{exc}\n\n"
301
+ "This often occurs when task inputs contain objects that cannot be cached "
302
+ "like locks, file handles, or other system resources.\n\n"
303
+ "To resolve this, you can:\n"
304
+ " 1. Exclude these arguments by defining a custom `cache_key_fn`\n"
305
+ " 2. Disable caching by passing `cache_policy=NONE`\n"
306
+ )
307
+ raise ValueError(msg) from exc
297
308
 
298
309
  def __sub__(self, other: str) -> "CachePolicy":
299
310
  if not isinstance(other, str):
@@ -13,7 +13,6 @@ from prefect.client.base import PrefectHttpxAsyncClient
13
13
  from prefect.client.schemas.objects import (
14
14
  IPAllowlist,
15
15
  IPAllowlistMyAccessResponse,
16
- KeyValueLabels,
17
16
  Workspace,
18
17
  )
19
18
  from prefect.exceptions import ObjectNotFound, PrefectException
@@ -23,6 +22,7 @@ from prefect.settings import (
23
22
  PREFECT_CLOUD_API_URL,
24
23
  PREFECT_TESTING_UNIT_TEST_MODE,
25
24
  )
25
+ from prefect.types import KeyValueLabels
26
26
 
27
27
  PARSE_API_URL_REGEX = re.compile(r"accounts/(.{36})/workspaces/(.{36})")
28
28
 
@@ -3925,13 +3925,13 @@ class SyncPrefectClient:
3925
3925
  def read_flow_runs(
3926
3926
  self,
3927
3927
  *,
3928
- flow_filter: FlowFilter = None,
3929
- flow_run_filter: FlowRunFilter = None,
3930
- task_run_filter: TaskRunFilter = None,
3931
- deployment_filter: DeploymentFilter = None,
3932
- work_pool_filter: WorkPoolFilter = None,
3933
- work_queue_filter: WorkQueueFilter = None,
3934
- sort: FlowRunSort = None,
3928
+ flow_filter: Optional[FlowFilter] = None,
3929
+ flow_run_filter: Optional[FlowRunFilter] = None,
3930
+ task_run_filter: Optional[TaskRunFilter] = None,
3931
+ deployment_filter: Optional[DeploymentFilter] = None,
3932
+ work_pool_filter: Optional[WorkPoolFilter] = None,
3933
+ work_queue_filter: Optional[WorkQueueFilter] = None,
3934
+ sort: Optional[FlowRunSort] = None,
3935
3935
  limit: Optional[int] = None,
3936
3936
  offset: int = 0,
3937
3937
  ) -> List[FlowRun]:
@@ -23,9 +23,6 @@ from pydantic import (
23
23
  HttpUrl,
24
24
  IPvAnyNetwork,
25
25
  SerializationInfo,
26
- StrictBool,
27
- StrictFloat,
28
- StrictInt,
29
26
  Tag,
30
27
  field_validator,
31
28
  model_serializer,
@@ -56,6 +53,7 @@ from prefect.client.schemas.schedules import SCHEDULE_TYPES
56
53
  from prefect.settings import PREFECT_CLOUD_API_URL, PREFECT_CLOUD_UI_URL
57
54
  from prefect.types import (
58
55
  MAX_VARIABLE_NAME_LENGTH,
56
+ KeyValueLabels,
59
57
  Name,
60
58
  NonNegativeInteger,
61
59
  PositiveInteger,
@@ -71,8 +69,6 @@ if TYPE_CHECKING:
71
69
 
72
70
  R = TypeVar("R", default=Any)
73
71
 
74
- KeyValueLabels = dict[str, Union[StrictBool, StrictInt, StrictFloat, str]]
75
-
76
72
 
77
73
  DEFAULT_BLOCK_SCHEMA_VERSION = "non-versioned"
78
74
  DEFAULT_AGENT_WORK_POOL_NAME = "default-agent-pool"
@@ -497,6 +493,9 @@ class FlowRunPolicy(PrefectBaseModel):
497
493
  resuming: Optional[bool] = Field(
498
494
  default=False, description="Indicates if this run is resuming from a pause."
499
495
  )
496
+ retry_type: Optional[Literal["in_process", "reschedule"]] = Field(
497
+ default=None, description="The type of retry this run is undergoing."
498
+ )
500
499
 
501
500
  @model_validator(mode="before")
502
501
  @classmethod
@@ -560,6 +559,11 @@ class FlowRun(ObjectBaseModel):
560
559
  description="A list of tags on the flow run",
561
560
  examples=[["tag-1", "tag-2"]],
562
561
  )
562
+ labels: KeyValueLabels = Field(
563
+ default_factory=dict,
564
+ description="Prefect Cloud: A dictionary of key-value labels. Values can be strings, numbers, or booleans.",
565
+ examples=[{"key": "value1", "key2": 42}],
566
+ )
563
567
  parent_task_run_id: Optional[UUID] = Field(
564
568
  default=None,
565
569
  description=(
@@ -1180,27 +1184,6 @@ class ConcurrencyLimit(ObjectBaseModel):
1180
1184
  )
1181
1185
 
1182
1186
 
1183
- class BlockSchema(ObjectBaseModel):
1184
- """An ORM representation of a block schema."""
1185
-
1186
- checksum: str = Field(default=..., description="The block schema's unique checksum")
1187
- fields: Dict[str, Any] = Field(
1188
- default_factory=dict, description="The block schema's field schema"
1189
- )
1190
- block_type_id: Optional[UUID] = Field(default=..., description="A block type ID")
1191
- block_type: Optional[BlockType] = Field(
1192
- default=None, description="The associated block type"
1193
- )
1194
- capabilities: List[str] = Field(
1195
- default_factory=list,
1196
- description="A list of Block capabilities",
1197
- )
1198
- version: str = Field(
1199
- default=DEFAULT_BLOCK_SCHEMA_VERSION,
1200
- description="Human readable identifier for the block schema",
1201
- )
1202
-
1203
-
1204
1187
  class BlockSchemaReference(ObjectBaseModel):
1205
1188
  """An ORM representation of a block schema reference."""
1206
1189
 
@@ -77,6 +77,7 @@ from prefect.settings import (
77
77
  PREFECT_DEFAULT_WORK_POOL_NAME,
78
78
  PREFECT_UI_URL,
79
79
  )
80
+ from prefect.types import ListOfNonEmptyStrings
80
81
  from prefect.types.entrypoint import EntrypointType
81
82
  from prefect.utilities.asyncutils import sync_compatible
82
83
  from prefect.utilities.callables import ParameterSchema, parameter_schema
@@ -140,7 +141,7 @@ class RunnerDeployment(BaseModel):
140
141
  version: Optional[str] = Field(
141
142
  default=None, description="An optional version for the deployment."
142
143
  )
143
- tags: List[str] = Field(
144
+ tags: ListOfNonEmptyStrings = Field(
144
145
  default_factory=list,
145
146
  description="One of more tags to apply to this deployment.",
146
147
  )
@@ -83,17 +83,18 @@ class EventOccurredFilter(EventDataFilter):
83
83
 
84
84
  class EventNameFilter(EventDataFilter):
85
85
  prefix: Optional[List[str]] = Field(
86
- None, description="Only include events matching one of these prefixes"
86
+ default=None, description="Only include events matching one of these prefixes"
87
87
  )
88
88
  exclude_prefix: Optional[List[str]] = Field(
89
- None, description="Exclude events matching one of these prefixes"
89
+ default=None, description="Exclude events matching one of these prefixes"
90
90
  )
91
91
 
92
92
  name: Optional[List[str]] = Field(
93
- None, description="Only include events matching one of these names exactly"
93
+ default=None,
94
+ description="Only include events matching one of these names exactly",
94
95
  )
95
96
  exclude_name: Optional[List[str]] = Field(
96
- None, description="Exclude events matching one of these names exactly"
97
+ default=None, description="Exclude events matching one of these names exactly"
97
98
  )
98
99
 
99
100
  def includes(self, event: Event) -> bool:
@@ -230,17 +231,20 @@ class EventFilter(EventDataFilter):
230
231
  description="Filter criteria for when the events occurred",
231
232
  )
232
233
  event: Optional[EventNameFilter] = Field(
233
- None,
234
+ default=None,
234
235
  description="Filter criteria for the event name",
235
236
  )
236
237
  any_resource: Optional[EventAnyResourceFilter] = Field(
237
- None, description="Filter criteria for any resource involved in the event"
238
+ default=None,
239
+ description="Filter criteria for any resource involved in the event",
238
240
  )
239
241
  resource: Optional[EventResourceFilter] = Field(
240
- None, description="Filter criteria for the resource of the event"
242
+ default=None,
243
+ description="Filter criteria for the resource of the event",
241
244
  )
242
245
  related: Optional[EventRelatedFilter] = Field(
243
- None, description="Filter criteria for the related resources of the event"
246
+ default=None,
247
+ description="Filter criteria for the related resources of the event",
244
248
  )
245
249
  id: EventIDFilter = Field(
246
250
  default_factory=lambda: EventIDFilter(id=[]),
@@ -248,6 +252,6 @@ class EventFilter(EventDataFilter):
248
252
  )
249
253
 
250
254
  order: EventOrder = Field(
251
- EventOrder.DESC,
255
+ default=EventOrder.DESC,
252
256
  description="The order to return filtered events",
253
257
  )
@@ -443,3 +443,7 @@ class ProfileSettingsValidationError(PrefectException):
443
443
 
444
444
  def __init__(self, errors: List[Tuple[Any, ValidationError]]) -> None:
445
445
  self.errors = errors
446
+
447
+
448
+ class HashError(PrefectException):
449
+ """Raised when hashing objects fails"""
@@ -22,8 +22,11 @@ from typing import (
22
22
  )
23
23
  from uuid import UUID
24
24
 
25
+ from opentelemetry import trace
26
+ from opentelemetry.trace import Tracer, get_tracer
25
27
  from typing_extensions import ParamSpec
26
28
 
29
+ import prefect
27
30
  from prefect import Task
28
31
  from prefect.client.orchestration import SyncPrefectClient, get_client
29
32
  from prefect.client.schemas import FlowRun, TaskRun
@@ -124,6 +127,10 @@ class FlowRunEngine(Generic[P, R]):
124
127
  _client: Optional[SyncPrefectClient] = None
125
128
  short_circuit: bool = False
126
129
  _flow_run_name_set: bool = False
130
+ _tracer: Tracer = field(
131
+ default_factory=lambda: get_tracer("prefect", prefect.__version__)
132
+ )
133
+ _span: Optional[trace.Span] = None
127
134
 
128
135
  def __post_init__(self):
129
136
  if self.flow is None and self.flow_run_id is None:
@@ -233,6 +240,17 @@ class FlowRunEngine(Generic[P, R]):
233
240
  self.flow_run.state = state # type: ignore
234
241
  self.flow_run.state_name = state.name # type: ignore
235
242
  self.flow_run.state_type = state.type # type: ignore
243
+
244
+ if self._span:
245
+ self._span.add_event(
246
+ state.name,
247
+ {
248
+ "prefect.state.message": state.message or "",
249
+ "prefect.state.type": state.type,
250
+ "prefect.state.name": state.name or state.type,
251
+ "prefect.state.id": str(state.id),
252
+ },
253
+ )
236
254
  return state
237
255
 
238
256
  def result(self, raise_on_failure: bool = True) -> "Union[R, State, None]":
@@ -281,6 +299,9 @@ class FlowRunEngine(Generic[P, R]):
281
299
  )
282
300
  self.set_state(terminal_state)
283
301
  self._return_value = resolved_result
302
+
303
+ self._end_span_on_success()
304
+
284
305
  return result
285
306
 
286
307
  def handle_exception(
@@ -311,6 +332,9 @@ class FlowRunEngine(Generic[P, R]):
311
332
  )
312
333
  state = self.set_state(Running())
313
334
  self._raised = exc
335
+
336
+ self._end_span_on_error(exc, state.message)
337
+
314
338
  return state
315
339
 
316
340
  def handle_timeout(self, exc: TimeoutError) -> None:
@@ -329,6 +353,8 @@ class FlowRunEngine(Generic[P, R]):
329
353
  self.set_state(state)
330
354
  self._raised = exc
331
355
 
356
+ self._end_span_on_error(exc, message)
357
+
332
358
  def handle_crash(self, exc: BaseException) -> None:
333
359
  state = run_coro_as_sync(exception_to_crashed_state(exc))
334
360
  self.logger.error(f"Crash detected! {state.message}")
@@ -336,6 +362,23 @@ class FlowRunEngine(Generic[P, R]):
336
362
  self.set_state(state, force=True)
337
363
  self._raised = exc
338
364
 
365
+ self._end_span_on_error(exc, state.message)
366
+
367
+ def _end_span_on_success(self):
368
+ if not self._span:
369
+ return
370
+ self._span.set_status(trace.Status(trace.StatusCode.OK))
371
+ self._span.end(time.time_ns())
372
+ self._span = None
373
+
374
+ def _end_span_on_error(self, exc: BaseException, description: Optional[str]):
375
+ if not self._span:
376
+ return
377
+ self._span.record_exception(exc)
378
+ self._span.set_status(trace.Status(trace.StatusCode.ERROR, description))
379
+ self._span.end(time.time_ns())
380
+ self._span = None
381
+
339
382
  def load_subflow_run(
340
383
  self,
341
384
  parent_task_run: TaskRun,
@@ -578,6 +621,18 @@ class FlowRunEngine(Generic[P, R]):
578
621
  flow_version=self.flow.version,
579
622
  empirical_policy=self.flow_run.empirical_policy,
580
623
  )
624
+
625
+ self._span = self._tracer.start_span(
626
+ name=self.flow_run.name,
627
+ attributes={
628
+ **self.flow_run.labels,
629
+ "prefect.run.type": "flow",
630
+ "prefect.run.id": str(self.flow_run.id),
631
+ "prefect.tags": self.flow_run.tags,
632
+ "prefect.flow.name": self.flow.name,
633
+ },
634
+ )
635
+
581
636
  try:
582
637
  yield self
583
638
 
@@ -632,7 +687,7 @@ class FlowRunEngine(Generic[P, R]):
632
687
 
633
688
  @contextmanager
634
689
  def start(self) -> Generator[None, None, None]:
635
- with self.initialize_run():
690
+ with self.initialize_run(), trace.use_span(self._span):
636
691
  self.begin_run()
637
692
 
638
693
  if self.state.is_running():
@@ -32,7 +32,6 @@ from prefect.settings import (
32
32
  PREFECT_LOGGING_TO_API_BATCH_SIZE,
33
33
  PREFECT_LOGGING_TO_API_MAX_LOG_SIZE,
34
34
  PREFECT_LOGGING_TO_API_WHEN_MISSING_FLOW,
35
- get_current_settings,
36
35
  )
37
36
 
38
37
 
@@ -241,10 +240,12 @@ class APILogHandler(logging.Handler):
241
240
 
242
241
  class WorkerAPILogHandler(APILogHandler):
243
242
  def emit(self, record: logging.LogRecord):
244
- if get_current_settings().experiments.worker_logging_to_api_enabled:
245
- super().emit(record)
246
- else:
243
+ # Open-source API servers do not currently support worker logs, and
244
+ # worker logs only have an associated worker ID when connected to Cloud,
245
+ # so we won't send worker logs to the API unless they have a worker ID.
246
+ if not getattr(record, "worker_id", None):
247
247
  return
248
+ super().emit(record)
248
249
 
249
250
  def prepare(self, record: logging.LogRecord) -> Dict[str, Any]:
250
251
  """
@@ -18,11 +18,6 @@ class ExperimentsSettings(PrefectBaseSettings):
18
18
  ),
19
19
  )
20
20
 
21
- worker_logging_to_api_enabled: bool = Field(
22
- default=False,
23
- description="Enables the logging of worker logs to Prefect Cloud.",
24
- )
25
-
26
21
  telemetry_enabled: bool = Field(
27
22
  default=False,
28
23
  description="Enables sending telemetry to Prefect Cloud.",
@@ -1,6 +1,6 @@
1
1
  import time
2
2
  from threading import Event, Lock, Thread
3
- from typing import Optional
3
+ from typing import Dict, Optional
4
4
 
5
5
  from opentelemetry.context import Context
6
6
  from opentelemetry.sdk.trace import ReadableSpan, Span, SpanProcessor
@@ -10,7 +10,7 @@ from opentelemetry.sdk.trace.export import SpanExporter
10
10
  class InFlightSpanProcessor(SpanProcessor):
11
11
  def __init__(self, span_exporter: SpanExporter):
12
12
  self.span_exporter = span_exporter
13
- self._in_flight = {}
13
+ self._in_flight: Dict[int, Span] = {}
14
14
  self._lock = Lock()
15
15
  self._stop_event = Event()
16
16
  self._export_thread = Thread(target=self._export_periodically, daemon=True)
@@ -86,10 +86,26 @@ StrictVariableValue = Annotated[VariableValue, BeforeValidator(check_variable_va
86
86
 
87
87
  LaxUrl = Annotated[str, BeforeValidator(lambda x: str(x).strip())]
88
88
 
89
-
90
89
  StatusCode = Annotated[int, Field(ge=100, le=599)]
91
90
 
92
91
 
92
+ def cast_none_to_empty_dict(value: Any) -> dict[str, Any]:
93
+ if value is None:
94
+ return {}
95
+ return value
96
+
97
+
98
+ KeyValueLabels = Annotated[
99
+ dict[str, Union[StrictBool, StrictInt, StrictFloat, str]],
100
+ BeforeValidator(cast_none_to_empty_dict),
101
+ ]
102
+
103
+
104
+ ListOfNonEmptyStrings = Annotated[
105
+ List[str], BeforeValidator(lambda x: [s for s in x if s.strip()])
106
+ ]
107
+
108
+
93
109
  class SecretDict(pydantic.Secret[Dict[str, Any]]):
94
110
  pass
95
111
 
@@ -137,6 +153,7 @@ __all__ = [
137
153
  "LogLevel",
138
154
  "NonNegativeInteger",
139
155
  "PositiveInteger",
156
+ "ListOfNonEmptyStrings",
140
157
  "NonNegativeFloat",
141
158
  "Name",
142
159
  "NameOrEmpty",
@@ -7,7 +7,7 @@ import pathlib
7
7
  import threading
8
8
  from contextlib import contextmanager
9
9
  from pathlib import Path, PureWindowsPath
10
- from typing import Optional, Union
10
+ from typing import Optional, Union, cast
11
11
 
12
12
  import fsspec
13
13
  import pathspec
@@ -22,8 +22,8 @@ def create_default_ignore_file(path: str) -> bool:
22
22
  Creates default ignore file in the provided path if one does not already exist; returns boolean specifying
23
23
  whether a file was created.
24
24
  """
25
- path = pathlib.Path(path)
26
- ignore_file = path / ".prefectignore"
25
+ _path = pathlib.Path(path)
26
+ ignore_file = _path / ".prefectignore"
27
27
  if ignore_file.exists():
28
28
  return False
29
29
  default_file = pathlib.Path(prefect.__module_path__) / ".prefectignore"
@@ -54,12 +54,34 @@ def filter_files(
54
54
  chdir_lock = threading.Lock()
55
55
 
56
56
 
57
+ def _normalize_path(path: Union[str, Path]) -> str:
58
+ """
59
+ Normalize a path, handling UNC paths on Windows specially.
60
+ """
61
+ path = Path(path)
62
+
63
+ # Handle UNC paths on Windows differently
64
+ if os.name == "nt" and str(path).startswith("\\\\"):
65
+ # For UNC paths, use absolute() instead of resolve()
66
+ # to avoid the Windows path resolution issues
67
+ return str(path.absolute())
68
+ else:
69
+ try:
70
+ # For non-UNC paths, try resolve() first
71
+ return str(path.resolve())
72
+ except OSError:
73
+ # Fallback to absolute() if resolve() fails
74
+ return str(path.absolute())
75
+
76
+
57
77
  @contextmanager
58
78
  def tmpchdir(path: str):
59
79
  """
60
- Change current-working directories for the duration of the context
80
+ Change current-working directories for the duration of the context,
81
+ with special handling for UNC paths on Windows.
61
82
  """
62
- path = os.path.abspath(path)
83
+ path = _normalize_path(path)
84
+
63
85
  if os.path.isfile(path) or (not os.path.exists(path) and not path.endswith("/")):
64
86
  path = os.path.dirname(path)
65
87
 
@@ -67,7 +89,12 @@ def tmpchdir(path: str):
67
89
 
68
90
  with chdir_lock:
69
91
  try:
70
- os.chdir(path)
92
+ # On Windows with UNC paths, we need to handle the directory change carefully
93
+ if os.name == "nt" and path.startswith("\\\\"):
94
+ # Use os.path.abspath to handle UNC paths
95
+ os.chdir(os.path.abspath(path))
96
+ else:
97
+ os.chdir(path)
71
98
  yield path
72
99
  finally:
73
100
  os.chdir(owd)
@@ -76,7 +103,7 @@ def tmpchdir(path: str):
76
103
  def filename(path: str) -> str:
77
104
  """Extract the file name from a path with remote file system support"""
78
105
  try:
79
- of: OpenFile = fsspec.open(path)
106
+ of: OpenFile = cast(OpenFile, fsspec.open(path))
80
107
  sep = of.fs.sep
81
108
  except (ImportError, AttributeError):
82
109
  sep = "\\" if "\\" in path else "/"
@@ -98,7 +125,7 @@ def is_local_path(path: Union[str, pathlib.Path, OpenFile]):
98
125
  else:
99
126
  raise TypeError(f"Invalid path of type {type(path).__name__!r}")
100
127
 
101
- return type(of.fs) == LocalFileSystem
128
+ return isinstance(of.fs, LocalFileSystem)
102
129
 
103
130
 
104
131
  def to_display_path(