UncountablePythonSDK 0.0.82__py3-none-any.whl → 0.0.132__py3-none-any.whl

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 UncountablePythonSDK might be problematic. Click here for more details.

Files changed (298) hide show
  1. docs/conf.py +54 -7
  2. docs/index.md +107 -4
  3. docs/integration_examples/create_ingredient.md +43 -0
  4. docs/integration_examples/create_output.md +56 -0
  5. docs/integration_examples/index.md +6 -0
  6. docs/justfile +2 -2
  7. docs/requirements.txt +6 -4
  8. examples/basic_auth.py +7 -0
  9. examples/create_ingredient_sdk.py +34 -0
  10. examples/download_files.py +26 -0
  11. examples/integration-server/jobs/materials_auto/concurrent_cron.py +11 -0
  12. examples/integration-server/jobs/materials_auto/example_cron.py +3 -0
  13. examples/integration-server/jobs/materials_auto/example_http.py +47 -0
  14. examples/integration-server/jobs/materials_auto/example_instrument.py +100 -0
  15. examples/integration-server/jobs/materials_auto/example_parse.py +140 -0
  16. examples/integration-server/jobs/materials_auto/example_predictions.py +61 -0
  17. examples/integration-server/jobs/materials_auto/example_runsheet_wh.py +39 -0
  18. examples/integration-server/jobs/materials_auto/example_wh.py +17 -9
  19. examples/integration-server/jobs/materials_auto/profile.yaml +61 -0
  20. examples/integration-server/pyproject.toml +10 -10
  21. examples/oauth.py +7 -0
  22. examples/set_recipe_metadata_file.py +1 -1
  23. examples/upload_files.py +1 -2
  24. pkgs/argument_parser/__init__.py +8 -0
  25. pkgs/argument_parser/_is_namedtuple.py +3 -0
  26. pkgs/argument_parser/argument_parser.py +196 -63
  27. pkgs/filesystem_utils/__init__.py +1 -0
  28. pkgs/filesystem_utils/_blob_session.py +144 -0
  29. pkgs/filesystem_utils/_gdrive_session.py +5 -5
  30. pkgs/filesystem_utils/_s3_session.py +2 -1
  31. pkgs/filesystem_utils/_sftp_session.py +6 -3
  32. pkgs/filesystem_utils/file_type_utils.py +30 -10
  33. pkgs/serialization/__init__.py +7 -2
  34. pkgs/serialization/annotation.py +64 -0
  35. pkgs/serialization/missing_sentry.py +1 -1
  36. pkgs/serialization/opaque_key.py +1 -1
  37. pkgs/serialization/serial_alias.py +47 -0
  38. pkgs/serialization/serial_class.py +40 -48
  39. pkgs/serialization/serial_generic.py +16 -0
  40. pkgs/serialization/serial_union.py +16 -16
  41. pkgs/serialization_util/__init__.py +6 -0
  42. pkgs/serialization_util/dataclasses.py +14 -0
  43. pkgs/serialization_util/serialization_helpers.py +15 -5
  44. pkgs/type_spec/actions_registry/__main__.py +0 -4
  45. pkgs/type_spec/actions_registry/emit_typescript.py +2 -4
  46. pkgs/type_spec/builder.py +248 -70
  47. pkgs/type_spec/builder_types.py +9 -0
  48. pkgs/type_spec/config.py +40 -7
  49. pkgs/type_spec/cross_output_links.py +99 -0
  50. pkgs/type_spec/emit_open_api.py +121 -34
  51. pkgs/type_spec/emit_open_api_util.py +5 -5
  52. pkgs/type_spec/emit_python.py +277 -86
  53. pkgs/type_spec/emit_typescript.py +102 -29
  54. pkgs/type_spec/emit_typescript_util.py +66 -10
  55. pkgs/type_spec/load_types.py +16 -3
  56. pkgs/type_spec/non_discriminated_union_exceptions.py +14 -0
  57. pkgs/type_spec/open_api_util.py +29 -4
  58. pkgs/type_spec/parts/base.py.prepart +11 -8
  59. pkgs/type_spec/parts/base.ts.prepart +4 -0
  60. pkgs/type_spec/type_info/__main__.py +3 -1
  61. pkgs/type_spec/type_info/emit_type_info.py +115 -22
  62. pkgs/type_spec/ui_entry_actions/__init__.py +4 -0
  63. pkgs/type_spec/ui_entry_actions/generate_ui_entry_actions.py +308 -0
  64. pkgs/type_spec/util.py +3 -3
  65. pkgs/type_spec/value_spec/__main__.py +26 -9
  66. pkgs/type_spec/value_spec/convert_type.py +18 -0
  67. pkgs/type_spec/value_spec/emit_python.py +13 -3
  68. pkgs/type_spec/value_spec/types.py +1 -1
  69. uncountable/core/async_batch.py +1 -1
  70. uncountable/core/client.py +133 -34
  71. uncountable/core/environment.py +3 -3
  72. uncountable/core/file_upload.py +39 -15
  73. uncountable/integration/cli.py +116 -23
  74. uncountable/integration/construct_client.py +3 -3
  75. uncountable/integration/executors/executors.py +12 -2
  76. uncountable/integration/executors/generic_upload_executor.py +66 -14
  77. uncountable/integration/http_server/__init__.py +5 -0
  78. uncountable/integration/http_server/types.py +69 -0
  79. uncountable/integration/job.py +192 -7
  80. uncountable/integration/queue_runner/command_server/__init__.py +4 -0
  81. uncountable/integration/queue_runner/command_server/command_client.py +65 -0
  82. uncountable/integration/queue_runner/command_server/command_server.py +83 -5
  83. uncountable/integration/queue_runner/command_server/constants.py +4 -0
  84. uncountable/integration/queue_runner/command_server/protocol/command_server.proto +36 -0
  85. uncountable/integration/queue_runner/command_server/protocol/command_server_pb2.py +28 -11
  86. uncountable/integration/queue_runner/command_server/protocol/command_server_pb2.pyi +77 -1
  87. uncountable/integration/queue_runner/command_server/protocol/command_server_pb2_grpc.py +135 -0
  88. uncountable/integration/queue_runner/command_server/types.py +25 -2
  89. uncountable/integration/queue_runner/datastore/datastore_sqlite.py +168 -11
  90. uncountable/integration/queue_runner/datastore/interface.py +10 -0
  91. uncountable/integration/queue_runner/datastore/model.py +8 -1
  92. uncountable/integration/queue_runner/job_scheduler.py +63 -23
  93. uncountable/integration/queue_runner/queue_runner.py +10 -2
  94. uncountable/integration/queue_runner/worker.py +22 -17
  95. uncountable/integration/scan_profiles.py +1 -1
  96. uncountable/integration/scheduler.py +74 -25
  97. uncountable/integration/secret_retrieval/retrieve_secret.py +1 -1
  98. uncountable/integration/server.py +42 -12
  99. uncountable/integration/telemetry.py +63 -10
  100. uncountable/integration/webhook_server/entrypoint.py +39 -112
  101. uncountable/types/__init__.py +58 -1
  102. uncountable/types/api/batch/execute_batch.py +5 -6
  103. uncountable/types/api/batch/execute_batch_load_async.py +2 -3
  104. uncountable/types/api/chemical/convert_chemical_formats.py +10 -5
  105. uncountable/types/api/condition_parameters/__init__.py +1 -0
  106. uncountable/types/api/condition_parameters/upsert_condition_match.py +72 -0
  107. uncountable/types/api/entity/create_entities.py +7 -7
  108. uncountable/types/api/entity/create_entity.py +8 -8
  109. uncountable/types/api/entity/create_or_update_entity.py +48 -0
  110. uncountable/types/api/entity/export_entities.py +59 -0
  111. uncountable/types/api/entity/get_entities_data.py +3 -4
  112. uncountable/types/api/entity/grant_entity_permissions.py +6 -6
  113. uncountable/types/api/entity/list_aggregate.py +79 -0
  114. uncountable/types/api/entity/list_entities.py +34 -10
  115. uncountable/types/api/entity/lock_entity.py +4 -4
  116. uncountable/types/api/entity/lookup_entity.py +116 -0
  117. uncountable/types/api/entity/resolve_entity_ids.py +5 -6
  118. uncountable/types/api/entity/set_entity_field_values.py +44 -0
  119. uncountable/types/api/entity/set_values.py +3 -3
  120. uncountable/types/api/entity/transition_entity_phase.py +14 -7
  121. uncountable/types/api/entity/unlock_entity.py +3 -3
  122. uncountable/types/api/equipment/associate_equipment_input.py +2 -3
  123. uncountable/types/api/field_options/upsert_field_options.py +7 -7
  124. uncountable/types/api/files/__init__.py +1 -0
  125. uncountable/types/api/files/download_file.py +77 -0
  126. uncountable/types/api/id_source/list_id_source.py +6 -7
  127. uncountable/types/api/id_source/match_id_source.py +4 -5
  128. uncountable/types/api/input_groups/get_input_group_names.py +3 -4
  129. uncountable/types/api/inputs/create_inputs.py +10 -9
  130. uncountable/types/api/inputs/get_input_data.py +11 -12
  131. uncountable/types/api/inputs/get_input_names.py +6 -7
  132. uncountable/types/api/inputs/get_inputs_data.py +6 -7
  133. uncountable/types/api/inputs/set_input_attribute_values.py +5 -6
  134. uncountable/types/api/inputs/set_input_category.py +5 -5
  135. uncountable/types/api/inputs/set_input_subcategories.py +3 -3
  136. uncountable/types/api/inputs/set_intermediate_type.py +4 -4
  137. uncountable/types/api/integrations/__init__.py +1 -0
  138. uncountable/types/api/integrations/publish_realtime_data.py +41 -0
  139. uncountable/types/api/integrations/push_notification.py +49 -0
  140. uncountable/types/api/integrations/register_sockets_token.py +41 -0
  141. uncountable/types/api/listing/__init__.py +1 -0
  142. uncountable/types/api/listing/fetch_listing.py +58 -0
  143. uncountable/types/api/material_families/update_entity_material_families.py +3 -4
  144. uncountable/types/api/notebooks/__init__.py +1 -0
  145. uncountable/types/api/notebooks/add_notebook_content.py +119 -0
  146. uncountable/types/api/outputs/get_output_data.py +12 -13
  147. uncountable/types/api/outputs/get_output_names.py +5 -6
  148. uncountable/types/api/outputs/get_output_organization.py +173 -0
  149. uncountable/types/api/outputs/resolve_output_conditions.py +7 -8
  150. uncountable/types/api/permissions/set_core_permissions.py +16 -10
  151. uncountable/types/api/project/get_projects.py +6 -7
  152. uncountable/types/api/project/get_projects_data.py +7 -8
  153. uncountable/types/api/recipe_links/create_recipe_link.py +5 -5
  154. uncountable/types/api/recipe_links/remove_recipe_link.py +4 -4
  155. uncountable/types/api/recipe_metadata/get_recipe_metadata_data.py +6 -7
  156. uncountable/types/api/recipes/add_recipe_to_project.py +3 -3
  157. uncountable/types/api/recipes/add_time_series_data.py +64 -0
  158. uncountable/types/api/recipes/archive_recipes.py +4 -4
  159. uncountable/types/api/recipes/associate_recipe_as_input.py +5 -5
  160. uncountable/types/api/recipes/associate_recipe_as_lot.py +3 -3
  161. uncountable/types/api/recipes/clear_recipe_outputs.py +3 -3
  162. uncountable/types/api/recipes/create_mix_order.py +44 -0
  163. uncountable/types/api/recipes/create_recipe.py +8 -9
  164. uncountable/types/api/recipes/create_recipes.py +8 -9
  165. uncountable/types/api/recipes/disassociate_recipe_as_input.py +3 -3
  166. uncountable/types/api/recipes/edit_recipe_inputs.py +101 -24
  167. uncountable/types/api/recipes/get_column_calculation_values.py +4 -5
  168. uncountable/types/api/recipes/get_curve.py +4 -5
  169. uncountable/types/api/recipes/get_recipe_calculations.py +6 -7
  170. uncountable/types/api/recipes/get_recipe_links.py +3 -4
  171. uncountable/types/api/recipes/get_recipe_names.py +3 -4
  172. uncountable/types/api/recipes/get_recipe_output_metadata.py +5 -6
  173. uncountable/types/api/recipes/get_recipes_data.py +62 -34
  174. uncountable/types/api/recipes/lock_recipes.py +9 -8
  175. uncountable/types/api/recipes/remove_recipe_from_project.py +3 -3
  176. uncountable/types/api/recipes/set_recipe_inputs.py +9 -10
  177. uncountable/types/api/recipes/set_recipe_metadata.py +3 -3
  178. uncountable/types/api/recipes/set_recipe_output_annotations.py +11 -12
  179. uncountable/types/api/recipes/set_recipe_output_file.py +5 -6
  180. uncountable/types/api/recipes/set_recipe_outputs.py +24 -13
  181. uncountable/types/api/recipes/set_recipe_tags.py +14 -9
  182. uncountable/types/api/recipes/set_recipe_total.py +59 -0
  183. uncountable/types/api/recipes/unarchive_recipes.py +3 -3
  184. uncountable/types/api/recipes/unlock_recipes.py +7 -6
  185. uncountable/types/api/runsheet/__init__.py +1 -0
  186. uncountable/types/api/runsheet/complete_async_upload.py +41 -0
  187. uncountable/types/api/triggers/run_trigger.py +4 -4
  188. uncountable/types/api/uploader/complete_async_parse.py +46 -0
  189. uncountable/types/api/uploader/invoke_uploader.py +4 -5
  190. uncountable/types/api/user/__init__.py +1 -0
  191. uncountable/types/api/user/get_current_user_info.py +40 -0
  192. uncountable/types/async_batch.py +1 -1
  193. uncountable/types/async_batch_processor.py +506 -23
  194. uncountable/types/async_batch_t.py +35 -8
  195. uncountable/types/async_jobs.py +0 -1
  196. uncountable/types/async_jobs_t.py +1 -2
  197. uncountable/types/auth_retrieval.py +0 -1
  198. uncountable/types/auth_retrieval_t.py +6 -6
  199. uncountable/types/base.py +0 -1
  200. uncountable/types/base_t.py +11 -9
  201. uncountable/types/calculations.py +0 -1
  202. uncountable/types/calculations_t.py +1 -2
  203. uncountable/types/chemical_structure.py +0 -1
  204. uncountable/types/chemical_structure_t.py +5 -5
  205. uncountable/types/client_base.py +614 -69
  206. uncountable/types/client_config.py +1 -1
  207. uncountable/types/client_config_t.py +13 -3
  208. uncountable/types/curves.py +0 -1
  209. uncountable/types/curves_t.py +6 -7
  210. uncountable/types/data.py +12 -0
  211. uncountable/types/data_t.py +103 -0
  212. uncountable/types/entity.py +1 -1
  213. uncountable/types/entity_t.py +90 -10
  214. uncountable/types/experiment_groups.py +0 -1
  215. uncountable/types/experiment_groups_t.py +1 -2
  216. uncountable/types/exports.py +8 -0
  217. uncountable/types/exports_t.py +34 -0
  218. uncountable/types/field_values.py +19 -1
  219. uncountable/types/field_values_t.py +242 -9
  220. uncountable/types/fields.py +0 -1
  221. uncountable/types/fields_t.py +1 -2
  222. uncountable/types/generic_upload.py +0 -1
  223. uncountable/types/generic_upload_t.py +14 -14
  224. uncountable/types/id_source.py +0 -1
  225. uncountable/types/id_source_t.py +13 -7
  226. uncountable/types/identifier.py +0 -1
  227. uncountable/types/identifier_t.py +10 -5
  228. uncountable/types/input_attributes.py +0 -1
  229. uncountable/types/input_attributes_t.py +3 -4
  230. uncountable/types/inputs.py +0 -1
  231. uncountable/types/inputs_t.py +3 -4
  232. uncountable/types/integration_server.py +0 -1
  233. uncountable/types/integration_server_t.py +13 -4
  234. uncountable/types/integration_session.py +10 -0
  235. uncountable/types/integration_session_t.py +60 -0
  236. uncountable/types/integrations.py +10 -0
  237. uncountable/types/integrations_t.py +62 -0
  238. uncountable/types/job_definition.py +2 -1
  239. uncountable/types/job_definition_t.py +57 -32
  240. uncountable/types/listing.py +9 -0
  241. uncountable/types/listing_t.py +51 -0
  242. uncountable/types/notices.py +8 -0
  243. uncountable/types/notices_t.py +37 -0
  244. uncountable/types/notifications.py +11 -0
  245. uncountable/types/notifications_t.py +74 -0
  246. uncountable/types/outputs.py +0 -1
  247. uncountable/types/outputs_t.py +2 -3
  248. uncountable/types/overrides.py +0 -1
  249. uncountable/types/overrides_t.py +10 -4
  250. uncountable/types/permissions.py +0 -1
  251. uncountable/types/permissions_t.py +1 -2
  252. uncountable/types/phases.py +0 -1
  253. uncountable/types/phases_t.py +1 -2
  254. uncountable/types/post_base.py +0 -1
  255. uncountable/types/post_base_t.py +1 -2
  256. uncountable/types/queued_job.py +2 -1
  257. uncountable/types/queued_job_t.py +29 -12
  258. uncountable/types/recipe_identifiers.py +0 -1
  259. uncountable/types/recipe_identifiers_t.py +18 -8
  260. uncountable/types/recipe_inputs.py +0 -1
  261. uncountable/types/recipe_inputs_t.py +1 -2
  262. uncountable/types/recipe_links.py +0 -1
  263. uncountable/types/recipe_links_t.py +3 -4
  264. uncountable/types/recipe_metadata.py +0 -1
  265. uncountable/types/recipe_metadata_t.py +9 -10
  266. uncountable/types/recipe_output_metadata.py +0 -1
  267. uncountable/types/recipe_output_metadata_t.py +1 -2
  268. uncountable/types/recipe_tags.py +0 -1
  269. uncountable/types/recipe_tags_t.py +1 -2
  270. uncountable/types/recipe_workflow_steps.py +0 -1
  271. uncountable/types/recipe_workflow_steps_t.py +7 -7
  272. uncountable/types/recipes.py +0 -1
  273. uncountable/types/recipes_t.py +2 -2
  274. uncountable/types/response.py +0 -1
  275. uncountable/types/response_t.py +2 -2
  276. uncountable/types/secret_retrieval.py +0 -1
  277. uncountable/types/secret_retrieval_t.py +7 -7
  278. uncountable/types/sockets.py +20 -0
  279. uncountable/types/sockets_t.py +169 -0
  280. uncountable/types/structured_filters.py +25 -0
  281. uncountable/types/structured_filters_t.py +248 -0
  282. uncountable/types/units.py +0 -1
  283. uncountable/types/units_t.py +1 -2
  284. uncountable/types/uploader.py +24 -0
  285. uncountable/types/uploader_t.py +222 -0
  286. uncountable/types/users.py +0 -1
  287. uncountable/types/users_t.py +1 -2
  288. uncountable/types/webhook_job.py +1 -1
  289. uncountable/types/webhook_job_t.py +14 -3
  290. uncountable/types/workflows.py +0 -1
  291. uncountable/types/workflows_t.py +3 -4
  292. uncountablepythonsdk-0.0.132.dist-info/METADATA +64 -0
  293. uncountablepythonsdk-0.0.132.dist-info/RECORD +363 -0
  294. {UncountablePythonSDK-0.0.82.dist-info → uncountablepythonsdk-0.0.132.dist-info}/WHEEL +1 -1
  295. UncountablePythonSDK-0.0.82.dist-info/METADATA +0 -60
  296. UncountablePythonSDK-0.0.82.dist-info/RECORD +0 -292
  297. docs/quickstart.md +0 -19
  298. {UncountablePythonSDK-0.0.82.dist-info → uncountablepythonsdk-0.0.132.dist-info}/top_level.txt +0 -0
@@ -1,7 +1,9 @@
1
1
  import asyncio
2
2
 
3
+ import grpc.aio as grpc_aio
3
4
  import simplejson as json
4
- from grpc import aio
5
+ from google.protobuf.timestamp_pb2 import Timestamp
6
+ from grpc import StatusCode
5
7
 
6
8
  from pkgs.argument_parser import CachedParser
7
9
  from uncountable.core.environment import get_local_admin_server_port
@@ -10,14 +12,26 @@ from uncountable.integration.queue_runner.command_server.protocol.command_server
10
12
  CheckHealthResult,
11
13
  EnqueueJobRequest,
12
14
  EnqueueJobResult,
15
+ ListQueuedJobsRequest,
16
+ ListQueuedJobsResult,
17
+ RetryJobRequest,
18
+ RetryJobResult,
19
+ VaccuumQueuedJobsRequest,
20
+ VaccuumQueuedJobsResult,
13
21
  )
14
22
  from uncountable.integration.queue_runner.command_server.types import (
15
23
  CommandEnqueueJob,
16
24
  CommandEnqueueJobResponse,
17
25
  CommandQueue,
26
+ CommandRetryJob,
27
+ CommandRetryJobResponse,
28
+ CommandVaccuumQueuedJobs,
29
+ CommandVaccuumQueuedJobsResponse,
18
30
  )
31
+ from uncountable.integration.queue_runner.datastore import DatastoreSqlite
19
32
  from uncountable.types import queued_job_t
20
33
 
34
+ from .constants import ListQueuedJobsConstants
21
35
  from .protocol.command_server_pb2_grpc import (
22
36
  CommandServerServicer,
23
37
  add_CommandServerServicer_to_server,
@@ -26,12 +40,12 @@ from .protocol.command_server_pb2_grpc import (
26
40
  queued_job_payload_parser = CachedParser(queued_job_t.QueuedJobPayload)
27
41
 
28
42
 
29
- async def serve(command_queue: CommandQueue) -> None:
30
- server = aio.server()
43
+ async def serve(command_queue: CommandQueue, datastore: DatastoreSqlite) -> None:
44
+ server = grpc_aio.server()
31
45
 
32
46
  class CommandServerHandler(CommandServerServicer):
33
47
  async def EnqueueJob(
34
- self, request: EnqueueJobRequest, context: aio.ServicerContext
48
+ self, request: EnqueueJobRequest, context: grpc_aio.ServicerContext
35
49
  ) -> EnqueueJobResult:
36
50
  payload_json = json.loads(request.serialized_payload)
37
51
  payload = queued_job_payload_parser.parse_api(payload_json)
@@ -49,11 +63,75 @@ async def serve(command_queue: CommandQueue) -> None:
49
63
  )
50
64
  return result
51
65
 
66
+ async def RetryJob(
67
+ self, request: RetryJobRequest, context: grpc_aio.ServicerContext
68
+ ) -> RetryJobResult:
69
+ response_queue: asyncio.Queue[CommandRetryJobResponse] = asyncio.Queue()
70
+ await command_queue.put(
71
+ CommandRetryJob(
72
+ queued_job_uuid=request.uuid, response_queue=response_queue
73
+ )
74
+ )
75
+ response = await response_queue.get()
76
+ if response.queued_job_uuid is not None:
77
+ return RetryJobResult(
78
+ successfully_queued=True, queued_job_uuid=response.queued_job_uuid
79
+ )
80
+ else:
81
+ return RetryJobResult(successfully_queued=False, queued_job_uuid="")
82
+
52
83
  async def CheckHealth(
53
- self, request: CheckHealthRequest, context: aio.ServicerContext
84
+ self, request: CheckHealthRequest, context: grpc_aio.ServicerContext
54
85
  ) -> CheckHealthResult:
55
86
  return CheckHealthResult(success=True)
56
87
 
88
+ async def ListQueuedJobs(
89
+ self, request: ListQueuedJobsRequest, context: grpc_aio.ServicerContext
90
+ ) -> ListQueuedJobsResult:
91
+ if (
92
+ request.limit < ListQueuedJobsConstants.LIMIT_MIN
93
+ or request.limit > ListQueuedJobsConstants.LIMIT_MAX
94
+ ):
95
+ await context.abort(
96
+ StatusCode.INVALID_ARGUMENT, "Limit must be between 1 and 100."
97
+ )
98
+
99
+ if request.offset < ListQueuedJobsConstants.OFFSET_MIN:
100
+ await context.abort(
101
+ StatusCode.INVALID_ARGUMENT, "Offset cannot be negative."
102
+ )
103
+
104
+ queued_job_metadata = datastore.list_queued_job_metadata(
105
+ offset=request.offset, limit=request.limit
106
+ )
107
+
108
+ response_list: list[ListQueuedJobsResult.ListQueuedJobsResultItem] = []
109
+ for item in queued_job_metadata:
110
+ proto_timestamp = Timestamp()
111
+ proto_timestamp.FromDatetime(item.submitted_at)
112
+
113
+ response_list.append(
114
+ ListQueuedJobsResult.ListQueuedJobsResultItem(
115
+ uuid=item.queued_job_uuid,
116
+ job_ref_name=item.job_ref_name,
117
+ num_attempts=item.num_attempts,
118
+ submitted_at=proto_timestamp,
119
+ status=item.status,
120
+ )
121
+ )
122
+ return ListQueuedJobsResult(queued_jobs=response_list)
123
+
124
+ async def VaccuumQueuedJobs(
125
+ self, request: VaccuumQueuedJobsRequest, context: grpc_aio.ServicerContext
126
+ ) -> VaccuumQueuedJobsResult:
127
+ response_queue: asyncio.Queue[CommandVaccuumQueuedJobsResponse] = (
128
+ asyncio.Queue()
129
+ )
130
+ await command_queue.put(
131
+ CommandVaccuumQueuedJobs(response_queue=response_queue)
132
+ )
133
+ return VaccuumQueuedJobsResult()
134
+
57
135
  add_CommandServerServicer_to_server(CommandServerHandler(), server)
58
136
 
59
137
  listen_addr = f"[::]:{get_local_admin_server_port()}"
@@ -0,0 +1,4 @@
1
+ class ListQueuedJobsConstants:
2
+ LIMIT_MIN = 1
3
+ LIMIT_MAX = 100
4
+ OFFSET_MIN = 0
@@ -1,8 +1,12 @@
1
1
  syntax = "proto3";
2
+ import "google/protobuf/timestamp.proto";
2
3
 
3
4
  service CommandServer {
4
5
  rpc EnqueueJob(EnqueueJobRequest) returns (EnqueueJobResult) {}
6
+ rpc RetryJob(RetryJobRequest) returns (RetryJobResult) {}
5
7
  rpc CheckHealth(CheckHealthRequest) returns (CheckHealthResult) {}
8
+ rpc ListQueuedJobs(ListQueuedJobsRequest) returns (ListQueuedJobsResult) {}
9
+ rpc VaccuumQueuedJobs(VaccuumQueuedJobsRequest) returns (VaccuumQueuedJobsResult) {}
6
10
  }
7
11
 
8
12
  message EnqueueJobRequest {
@@ -15,8 +19,40 @@ message EnqueueJobResult {
15
19
  string queued_job_uuid = 2;
16
20
  }
17
21
 
22
+ message RetryJobRequest {
23
+ string uuid = 1;
24
+ }
25
+
26
+ message RetryJobResult {
27
+ bool successfully_queued = 1;
28
+ string queued_job_uuid = 2;
29
+ }
30
+
31
+ message VaccuumQueuedJobsRequest {
32
+ }
33
+
34
+ message VaccuumQueuedJobsResult {
35
+ }
36
+
18
37
  message CheckHealthRequest {}
19
38
 
20
39
  message CheckHealthResult {
21
40
  bool success = 1;
22
41
  }
42
+
43
+ message ListQueuedJobsRequest {
44
+ uint32 offset = 1;
45
+ uint32 limit = 2;
46
+ }
47
+
48
+ message ListQueuedJobsResult {
49
+ message ListQueuedJobsResultItem {
50
+ string uuid = 1;
51
+ string job_ref_name = 2;
52
+ int64 num_attempts = 3;
53
+ google.protobuf.Timestamp submitted_at = 4;
54
+ string status = 5;
55
+ }
56
+
57
+ repeated ListQueuedJobsResultItem queued_jobs = 1;
58
+ }
@@ -14,8 +14,11 @@ from google.protobuf.internal import builder as _builder
14
14
  _sym_db = _symbol_database.Default()
15
15
 
16
16
 
17
+ from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2
18
+
19
+
17
20
  DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(
18
- b'\nQuncountable/integration/queue_runner/command_server/protocol/command_server.proto"E\n\x11\x45nqueueJobRequest\x12\x14\n\x0cjob_ref_name\x18\x01 \x01(\t\x12\x1a\n\x12serialized_payload\x18\x02 \x01(\t"H\n\x10\x45nqueueJobResult\x12\x1b\n\x13successfully_queued\x18\x01 \x01(\x08\x12\x17\n\x0fqueued_job_uuid\x18\x02 \x01(\t"\x14\n\x12\x43heckHealthRequest"$\n\x11\x43heckHealthResult\x12\x0f\n\x07success\x18\x01 \x01(\x08\x32\x80\x01\n\rCommandServer\x12\x35\n\nEnqueueJob\x12\x12.EnqueueJobRequest\x1a\x11.EnqueueJobResult"\x00\x12\x38\n\x0b\x43heckHealth\x12\x13.CheckHealthRequest\x1a\x12.CheckHealthResult"\x00\x62\x06proto3'
21
+ b'\nQuncountable/integration/queue_runner/command_server/protocol/command_server.proto\x1a\x1fgoogle/protobuf/timestamp.proto"E\n\x11\x45nqueueJobRequest\x12\x14\n\x0cjob_ref_name\x18\x01 \x01(\t\x12\x1a\n\x12serialized_payload\x18\x02 \x01(\t"H\n\x10\x45nqueueJobResult\x12\x1b\n\x13successfully_queued\x18\x01 \x01(\x08\x12\x17\n\x0fqueued_job_uuid\x18\x02 \x01(\t"\x1f\n\x0fRetryJobRequest\x12\x0c\n\x04uuid\x18\x01 \x01(\t"F\n\x0eRetryJobResult\x12\x1b\n\x13successfully_queued\x18\x01 \x01(\x08\x12\x17\n\x0fqueued_job_uuid\x18\x02 \x01(\t"\x1a\n\x18VaccuumQueuedJobsRequest"\x19\n\x17VaccuumQueuedJobsResult"\x14\n\x12\x43heckHealthRequest"$\n\x11\x43heckHealthResult\x12\x0f\n\x07success\x18\x01 \x01(\x08"6\n\x15ListQueuedJobsRequest\x12\x0e\n\x06offset\x18\x01 \x01(\r\x12\r\n\x05limit\x18\x02 \x01(\r"\xf4\x01\n\x14ListQueuedJobsResult\x12\x43\n\x0bqueued_jobs\x18\x01 \x03(\x0b\x32..ListQueuedJobsResult.ListQueuedJobsResultItem\x1a\x96\x01\n\x18ListQueuedJobsResultItem\x12\x0c\n\x04uuid\x18\x01 \x01(\t\x12\x14\n\x0cjob_ref_name\x18\x02 \x01(\t\x12\x14\n\x0cnum_attempts\x18\x03 \x01(\x03\x12\x30\n\x0csubmitted_at\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x0e\n\x06status\x18\x05 \x01(\t2\xc0\x02\n\rCommandServer\x12\x35\n\nEnqueueJob\x12\x12.EnqueueJobRequest\x1a\x11.EnqueueJobResult"\x00\x12/\n\x08RetryJob\x12\x10.RetryJobRequest\x1a\x0f.RetryJobResult"\x00\x12\x38\n\x0b\x43heckHealth\x12\x13.CheckHealthRequest\x1a\x12.CheckHealthResult"\x00\x12\x41\n\x0eListQueuedJobs\x12\x16.ListQueuedJobsRequest\x1a\x15.ListQueuedJobsResult"\x00\x12J\n\x11VaccuumQueuedJobs\x12\x19.VaccuumQueuedJobsRequest\x1a\x18.VaccuumQueuedJobsResult"\x00\x62\x06proto3'
19
22
  )
20
23
 
21
24
  _globals = globals()
@@ -27,14 +30,28 @@ _builder.BuildTopDescriptorsAndMessages(
27
30
  )
28
31
  if _descriptor._USE_C_DESCRIPTORS == False:
29
32
  DESCRIPTOR._options = None
30
- _globals["_ENQUEUEJOBREQUEST"]._serialized_start = 85
31
- _globals["_ENQUEUEJOBREQUEST"]._serialized_end = 154
32
- _globals["_ENQUEUEJOBRESULT"]._serialized_start = 156
33
- _globals["_ENQUEUEJOBRESULT"]._serialized_end = 228
34
- _globals["_CHECKHEALTHREQUEST"]._serialized_start = 230
35
- _globals["_CHECKHEALTHREQUEST"]._serialized_end = 250
36
- _globals["_CHECKHEALTHRESULT"]._serialized_start = 252
37
- _globals["_CHECKHEALTHRESULT"]._serialized_end = 288
38
- _globals["_COMMANDSERVER"]._serialized_start = 291
39
- _globals["_COMMANDSERVER"]._serialized_end = 419
33
+ _globals["_ENQUEUEJOBREQUEST"]._serialized_start = 118
34
+ _globals["_ENQUEUEJOBREQUEST"]._serialized_end = 187
35
+ _globals["_ENQUEUEJOBRESULT"]._serialized_start = 189
36
+ _globals["_ENQUEUEJOBRESULT"]._serialized_end = 261
37
+ _globals["_RETRYJOBREQUEST"]._serialized_start = 263
38
+ _globals["_RETRYJOBREQUEST"]._serialized_end = 294
39
+ _globals["_RETRYJOBRESULT"]._serialized_start = 296
40
+ _globals["_RETRYJOBRESULT"]._serialized_end = 366
41
+ _globals["_VACCUUMQUEUEDJOBSREQUEST"]._serialized_start = 368
42
+ _globals["_VACCUUMQUEUEDJOBSREQUEST"]._serialized_end = 394
43
+ _globals["_VACCUUMQUEUEDJOBSRESULT"]._serialized_start = 396
44
+ _globals["_VACCUUMQUEUEDJOBSRESULT"]._serialized_end = 421
45
+ _globals["_CHECKHEALTHREQUEST"]._serialized_start = 423
46
+ _globals["_CHECKHEALTHREQUEST"]._serialized_end = 443
47
+ _globals["_CHECKHEALTHRESULT"]._serialized_start = 445
48
+ _globals["_CHECKHEALTHRESULT"]._serialized_end = 481
49
+ _globals["_LISTQUEUEDJOBSREQUEST"]._serialized_start = 483
50
+ _globals["_LISTQUEUEDJOBSREQUEST"]._serialized_end = 537
51
+ _globals["_LISTQUEUEDJOBSRESULT"]._serialized_start = 540
52
+ _globals["_LISTQUEUEDJOBSRESULT"]._serialized_end = 784
53
+ _globals["_LISTQUEUEDJOBSRESULT_LISTQUEUEDJOBSRESULTITEM"]._serialized_start = 634
54
+ _globals["_LISTQUEUEDJOBSRESULT_LISTQUEUEDJOBSRESULTITEM"]._serialized_end = 784
55
+ _globals["_COMMANDSERVER"]._serialized_start = 787
56
+ _globals["_COMMANDSERVER"]._serialized_end = 1107
40
57
  # @@protoc_insertion_point(module_scope)
@@ -1,7 +1,15 @@
1
1
  # ruff: noqa
2
+ from google.protobuf import timestamp_pb2 as _timestamp_pb2
3
+ from google.protobuf.internal import containers as _containers
2
4
  from google.protobuf import descriptor as _descriptor
3
5
  from google.protobuf import message as _message
4
- from typing import ClassVar as _ClassVar, Optional as _Optional
6
+ from typing import (
7
+ ClassVar as _ClassVar,
8
+ Iterable as _Iterable,
9
+ Mapping as _Mapping,
10
+ Optional as _Optional,
11
+ Union as _Union,
12
+ )
5
13
 
6
14
  DESCRIPTOR: _descriptor.FileDescriptor
7
15
 
@@ -27,6 +35,30 @@ class EnqueueJobResult(_message.Message):
27
35
  self, successfully_queued: bool = ..., queued_job_uuid: _Optional[str] = ...
28
36
  ) -> None: ...
29
37
 
38
+ class RetryJobRequest(_message.Message):
39
+ __slots__ = ("uuid",)
40
+ UUID_FIELD_NUMBER: _ClassVar[int]
41
+ uuid: str
42
+ def __init__(self, uuid: _Optional[str] = ...) -> None: ...
43
+
44
+ class RetryJobResult(_message.Message):
45
+ __slots__ = ("successfully_queued", "queued_job_uuid")
46
+ SUCCESSFULLY_QUEUED_FIELD_NUMBER: _ClassVar[int]
47
+ QUEUED_JOB_UUID_FIELD_NUMBER: _ClassVar[int]
48
+ successfully_queued: bool
49
+ queued_job_uuid: str
50
+ def __init__(
51
+ self, successfully_queued: bool = ..., queued_job_uuid: _Optional[str] = ...
52
+ ) -> None: ...
53
+
54
+ class VaccuumQueuedJobsRequest(_message.Message):
55
+ __slots__ = ()
56
+ def __init__(self) -> None: ...
57
+
58
+ class VaccuumQueuedJobsResult(_message.Message):
59
+ __slots__ = ()
60
+ def __init__(self) -> None: ...
61
+
30
62
  class CheckHealthRequest(_message.Message):
31
63
  __slots__ = ()
32
64
  def __init__(self) -> None: ...
@@ -36,3 +68,47 @@ class CheckHealthResult(_message.Message):
36
68
  SUCCESS_FIELD_NUMBER: _ClassVar[int]
37
69
  success: bool
38
70
  def __init__(self, success: bool = ...) -> None: ...
71
+
72
+ class ListQueuedJobsRequest(_message.Message):
73
+ __slots__ = ("offset", "limit")
74
+ OFFSET_FIELD_NUMBER: _ClassVar[int]
75
+ LIMIT_FIELD_NUMBER: _ClassVar[int]
76
+ offset: int
77
+ limit: int
78
+ def __init__(
79
+ self, offset: _Optional[int] = ..., limit: _Optional[int] = ...
80
+ ) -> None: ...
81
+
82
+ class ListQueuedJobsResult(_message.Message):
83
+ __slots__ = ("queued_jobs",)
84
+ class ListQueuedJobsResultItem(_message.Message):
85
+ __slots__ = ("uuid", "job_ref_name", "num_attempts", "submitted_at", "status")
86
+ UUID_FIELD_NUMBER: _ClassVar[int]
87
+ JOB_REF_NAME_FIELD_NUMBER: _ClassVar[int]
88
+ NUM_ATTEMPTS_FIELD_NUMBER: _ClassVar[int]
89
+ SUBMITTED_AT_FIELD_NUMBER: _ClassVar[int]
90
+ STATUS_FIELD_NUMBER: _ClassVar[int]
91
+ uuid: str
92
+ job_ref_name: str
93
+ num_attempts: int
94
+ submitted_at: _timestamp_pb2.Timestamp
95
+ status: str
96
+ def __init__(
97
+ self,
98
+ uuid: _Optional[str] = ...,
99
+ job_ref_name: _Optional[str] = ...,
100
+ num_attempts: _Optional[int] = ...,
101
+ submitted_at: _Optional[_Union[_timestamp_pb2.Timestamp, _Mapping]] = ...,
102
+ status: _Optional[str] = ...,
103
+ ) -> None: ...
104
+
105
+ QUEUED_JOBS_FIELD_NUMBER: _ClassVar[int]
106
+ queued_jobs: _containers.RepeatedCompositeFieldContainer[
107
+ ListQueuedJobsResult.ListQueuedJobsResultItem
108
+ ]
109
+ def __init__(
110
+ self,
111
+ queued_jobs: _Optional[
112
+ _Iterable[_Union[ListQueuedJobsResult.ListQueuedJobsResultItem, _Mapping]]
113
+ ] = ...,
114
+ ) -> None: ...
@@ -24,11 +24,26 @@ class CommandServerStub(object):
24
24
  request_serializer=uncountable_dot_integration_dot_queue__runner_dot_command__server_dot_protocol_dot_command__server__pb2.EnqueueJobRequest.SerializeToString,
25
25
  response_deserializer=uncountable_dot_integration_dot_queue__runner_dot_command__server_dot_protocol_dot_command__server__pb2.EnqueueJobResult.FromString,
26
26
  )
27
+ self.RetryJob = channel.unary_unary(
28
+ "/CommandServer/RetryJob",
29
+ request_serializer=uncountable_dot_integration_dot_queue__runner_dot_command__server_dot_protocol_dot_command__server__pb2.RetryJobRequest.SerializeToString,
30
+ response_deserializer=uncountable_dot_integration_dot_queue__runner_dot_command__server_dot_protocol_dot_command__server__pb2.RetryJobResult.FromString,
31
+ )
27
32
  self.CheckHealth = channel.unary_unary(
28
33
  "/CommandServer/CheckHealth",
29
34
  request_serializer=uncountable_dot_integration_dot_queue__runner_dot_command__server_dot_protocol_dot_command__server__pb2.CheckHealthRequest.SerializeToString,
30
35
  response_deserializer=uncountable_dot_integration_dot_queue__runner_dot_command__server_dot_protocol_dot_command__server__pb2.CheckHealthResult.FromString,
31
36
  )
37
+ self.ListQueuedJobs = channel.unary_unary(
38
+ "/CommandServer/ListQueuedJobs",
39
+ request_serializer=uncountable_dot_integration_dot_queue__runner_dot_command__server_dot_protocol_dot_command__server__pb2.ListQueuedJobsRequest.SerializeToString,
40
+ response_deserializer=uncountable_dot_integration_dot_queue__runner_dot_command__server_dot_protocol_dot_command__server__pb2.ListQueuedJobsResult.FromString,
41
+ )
42
+ self.VaccuumQueuedJobs = channel.unary_unary(
43
+ "/CommandServer/VaccuumQueuedJobs",
44
+ request_serializer=uncountable_dot_integration_dot_queue__runner_dot_command__server_dot_protocol_dot_command__server__pb2.VaccuumQueuedJobsRequest.SerializeToString,
45
+ response_deserializer=uncountable_dot_integration_dot_queue__runner_dot_command__server_dot_protocol_dot_command__server__pb2.VaccuumQueuedJobsResult.FromString,
46
+ )
32
47
 
33
48
 
34
49
  class CommandServerServicer(object):
@@ -40,12 +55,30 @@ class CommandServerServicer(object):
40
55
  context.set_details("Method not implemented!")
41
56
  raise NotImplementedError("Method not implemented!")
42
57
 
58
+ def RetryJob(self, request, context):
59
+ """Missing associated documentation comment in .proto file."""
60
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
61
+ context.set_details("Method not implemented!")
62
+ raise NotImplementedError("Method not implemented!")
63
+
43
64
  def CheckHealth(self, request, context):
44
65
  """Missing associated documentation comment in .proto file."""
45
66
  context.set_code(grpc.StatusCode.UNIMPLEMENTED)
46
67
  context.set_details("Method not implemented!")
47
68
  raise NotImplementedError("Method not implemented!")
48
69
 
70
+ def ListQueuedJobs(self, request, context):
71
+ """Missing associated documentation comment in .proto file."""
72
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
73
+ context.set_details("Method not implemented!")
74
+ raise NotImplementedError("Method not implemented!")
75
+
76
+ def VaccuumQueuedJobs(self, request, context):
77
+ """Missing associated documentation comment in .proto file."""
78
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
79
+ context.set_details("Method not implemented!")
80
+ raise NotImplementedError("Method not implemented!")
81
+
49
82
 
50
83
  def add_CommandServerServicer_to_server(servicer, server):
51
84
  rpc_method_handlers = {
@@ -54,11 +87,26 @@ def add_CommandServerServicer_to_server(servicer, server):
54
87
  request_deserializer=uncountable_dot_integration_dot_queue__runner_dot_command__server_dot_protocol_dot_command__server__pb2.EnqueueJobRequest.FromString,
55
88
  response_serializer=uncountable_dot_integration_dot_queue__runner_dot_command__server_dot_protocol_dot_command__server__pb2.EnqueueJobResult.SerializeToString,
56
89
  ),
90
+ "RetryJob": grpc.unary_unary_rpc_method_handler(
91
+ servicer.RetryJob,
92
+ request_deserializer=uncountable_dot_integration_dot_queue__runner_dot_command__server_dot_protocol_dot_command__server__pb2.RetryJobRequest.FromString,
93
+ response_serializer=uncountable_dot_integration_dot_queue__runner_dot_command__server_dot_protocol_dot_command__server__pb2.RetryJobResult.SerializeToString,
94
+ ),
57
95
  "CheckHealth": grpc.unary_unary_rpc_method_handler(
58
96
  servicer.CheckHealth,
59
97
  request_deserializer=uncountable_dot_integration_dot_queue__runner_dot_command__server_dot_protocol_dot_command__server__pb2.CheckHealthRequest.FromString,
60
98
  response_serializer=uncountable_dot_integration_dot_queue__runner_dot_command__server_dot_protocol_dot_command__server__pb2.CheckHealthResult.SerializeToString,
61
99
  ),
100
+ "ListQueuedJobs": grpc.unary_unary_rpc_method_handler(
101
+ servicer.ListQueuedJobs,
102
+ request_deserializer=uncountable_dot_integration_dot_queue__runner_dot_command__server_dot_protocol_dot_command__server__pb2.ListQueuedJobsRequest.FromString,
103
+ response_serializer=uncountable_dot_integration_dot_queue__runner_dot_command__server_dot_protocol_dot_command__server__pb2.ListQueuedJobsResult.SerializeToString,
104
+ ),
105
+ "VaccuumQueuedJobs": grpc.unary_unary_rpc_method_handler(
106
+ servicer.VaccuumQueuedJobs,
107
+ request_deserializer=uncountable_dot_integration_dot_queue__runner_dot_command__server_dot_protocol_dot_command__server__pb2.VaccuumQueuedJobsRequest.FromString,
108
+ response_serializer=uncountable_dot_integration_dot_queue__runner_dot_command__server_dot_protocol_dot_command__server__pb2.VaccuumQueuedJobsResult.SerializeToString,
109
+ ),
62
110
  }
63
111
  generic_handler = grpc.method_handlers_generic_handler(
64
112
  "CommandServer", rpc_method_handlers
@@ -99,6 +147,35 @@ class CommandServer(object):
99
147
  metadata,
100
148
  )
101
149
 
150
+ @staticmethod
151
+ def RetryJob(
152
+ request,
153
+ target,
154
+ options=(),
155
+ channel_credentials=None,
156
+ call_credentials=None,
157
+ insecure=False,
158
+ compression=None,
159
+ wait_for_ready=None,
160
+ timeout=None,
161
+ metadata=None,
162
+ ):
163
+ return grpc.experimental.unary_unary(
164
+ request,
165
+ target,
166
+ "/CommandServer/RetryJob",
167
+ uncountable_dot_integration_dot_queue__runner_dot_command__server_dot_protocol_dot_command__server__pb2.RetryJobRequest.SerializeToString,
168
+ uncountable_dot_integration_dot_queue__runner_dot_command__server_dot_protocol_dot_command__server__pb2.RetryJobResult.FromString,
169
+ options,
170
+ channel_credentials,
171
+ insecure,
172
+ call_credentials,
173
+ compression,
174
+ wait_for_ready,
175
+ timeout,
176
+ metadata,
177
+ )
178
+
102
179
  @staticmethod
103
180
  def CheckHealth(
104
181
  request,
@@ -127,3 +204,61 @@ class CommandServer(object):
127
204
  timeout,
128
205
  metadata,
129
206
  )
207
+
208
+ @staticmethod
209
+ def ListQueuedJobs(
210
+ request,
211
+ target,
212
+ options=(),
213
+ channel_credentials=None,
214
+ call_credentials=None,
215
+ insecure=False,
216
+ compression=None,
217
+ wait_for_ready=None,
218
+ timeout=None,
219
+ metadata=None,
220
+ ):
221
+ return grpc.experimental.unary_unary(
222
+ request,
223
+ target,
224
+ "/CommandServer/ListQueuedJobs",
225
+ uncountable_dot_integration_dot_queue__runner_dot_command__server_dot_protocol_dot_command__server__pb2.ListQueuedJobsRequest.SerializeToString,
226
+ uncountable_dot_integration_dot_queue__runner_dot_command__server_dot_protocol_dot_command__server__pb2.ListQueuedJobsResult.FromString,
227
+ options,
228
+ channel_credentials,
229
+ insecure,
230
+ call_credentials,
231
+ compression,
232
+ wait_for_ready,
233
+ timeout,
234
+ metadata,
235
+ )
236
+
237
+ @staticmethod
238
+ def VaccuumQueuedJobs(
239
+ request,
240
+ target,
241
+ options=(),
242
+ channel_credentials=None,
243
+ call_credentials=None,
244
+ insecure=False,
245
+ compression=None,
246
+ wait_for_ready=None,
247
+ timeout=None,
248
+ metadata=None,
249
+ ):
250
+ return grpc.experimental.unary_unary(
251
+ request,
252
+ target,
253
+ "/CommandServer/VaccuumQueuedJobs",
254
+ uncountable_dot_integration_dot_queue__runner_dot_command__server_dot_protocol_dot_command__server__pb2.VaccuumQueuedJobsRequest.SerializeToString,
255
+ uncountable_dot_integration_dot_queue__runner_dot_command__server_dot_protocol_dot_command__server__pb2.VaccuumQueuedJobsResult.FromString,
256
+ options,
257
+ channel_credentials,
258
+ insecure,
259
+ call_credentials,
260
+ compression,
261
+ wait_for_ready,
262
+ timeout,
263
+ metadata,
264
+ )
@@ -8,13 +8,15 @@ from uncountable.types import queued_job_t
8
8
 
9
9
  class CommandType(StrEnum):
10
10
  ENQUEUE_JOB = "enqueue_job"
11
+ RETRY_JOB = "retry_job"
12
+ VACCUUM_QUEUED_JOBS = "vaccuum_queued_jobs"
11
13
 
12
14
 
13
15
  RT = typing.TypeVar("RT")
14
16
 
15
17
 
16
18
  @dataclass(kw_only=True)
17
- class CommandBase(typing.Generic[RT]):
19
+ class CommandBase[RT]:
18
20
  type: CommandType
19
21
  response_queue: asyncio.Queue[RT]
20
22
 
@@ -24,6 +26,16 @@ class CommandEnqueueJobResponse:
24
26
  queued_job_uuid: str
25
27
 
26
28
 
29
+ @dataclass(kw_only=True)
30
+ class CommandRetryJobResponse:
31
+ queued_job_uuid: str | None
32
+
33
+
34
+ @dataclass(kw_only=True)
35
+ class CommandVaccuumQueuedJobsResponse:
36
+ pass
37
+
38
+
27
39
  @dataclass(kw_only=True)
28
40
  class CommandEnqueueJob(CommandBase[CommandEnqueueJobResponse]):
29
41
  type: CommandType = CommandType.ENQUEUE_JOB
@@ -32,7 +44,18 @@ class CommandEnqueueJob(CommandBase[CommandEnqueueJobResponse]):
32
44
  response_queue: asyncio.Queue[CommandEnqueueJobResponse]
33
45
 
34
46
 
35
- _Command = CommandEnqueueJob
47
+ @dataclass(kw_only=True)
48
+ class CommandRetryJob(CommandBase[CommandRetryJobResponse]):
49
+ type: CommandType = CommandType.RETRY_JOB
50
+ queued_job_uuid: str
51
+
52
+
53
+ @dataclass(kw_only=True)
54
+ class CommandVaccuumQueuedJobs(CommandBase[CommandVaccuumQueuedJobsResponse]):
55
+ type: CommandType = CommandType.VACCUUM_QUEUED_JOBS
56
+
57
+
58
+ _Command = CommandEnqueueJob | CommandRetryJob | CommandVaccuumQueuedJobs
36
59
 
37
60
 
38
61
  CommandQueue = asyncio.Queue[_Command]