gatewaysdk 0.3.2__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.
Files changed (376) hide show
  1. gatewaysdk/__init__.py +540 -0
  2. gatewaysdk/adapter/__init__.py +15 -0
  3. gatewaysdk/adapter/base.py +94 -0
  4. gatewaysdk/adapter/messages.py +270 -0
  5. gatewaysdk/adapter/triplet.py +1026 -0
  6. gatewaysdk/algorithm/__init__.py +39 -0
  7. gatewaysdk/algorithm/apo/__init__.py +5 -0
  8. gatewaysdk/algorithm/apo/apo.py +898 -0
  9. gatewaysdk/algorithm/apo/prompts/apply_edit_variant01.poml +22 -0
  10. gatewaysdk/algorithm/apo/prompts/apply_edit_variant02.poml +18 -0
  11. gatewaysdk/algorithm/apo/prompts/text_gradient_variant01.poml +18 -0
  12. gatewaysdk/algorithm/apo/prompts/text_gradient_variant02.poml +16 -0
  13. gatewaysdk/algorithm/apo/prompts/text_gradient_variant03.poml +107 -0
  14. gatewaysdk/algorithm/base.py +262 -0
  15. gatewaysdk/algorithm/decorator.py +264 -0
  16. gatewaysdk/algorithm/evals/__init__.py +7 -0
  17. gatewaysdk/algorithm/evals/evals.py +217 -0
  18. gatewaysdk/algorithm/fast.py +250 -0
  19. gatewaysdk/algorithm/gepa/__init__.py +61 -0
  20. gatewaysdk/algorithm/gepa/adapter.py +495 -0
  21. gatewaysdk/algorithm/gepa/gepa.py +570 -0
  22. gatewaysdk/algorithm/gepa/lib/__init__.py +18 -0
  23. gatewaysdk/algorithm/gepa/lib/adapters/README.md +12 -0
  24. gatewaysdk/algorithm/gepa/lib/adapters/__init__.py +0 -0
  25. gatewaysdk/algorithm/gepa/lib/adapters/anymaths_adapter/README.md +341 -0
  26. gatewaysdk/algorithm/gepa/lib/adapters/anymaths_adapter/__init__.py +1 -0
  27. gatewaysdk/algorithm/gepa/lib/adapters/anymaths_adapter/anymaths_adapter.py +174 -0
  28. gatewaysdk/algorithm/gepa/lib/adapters/anymaths_adapter/requirements.txt +1 -0
  29. gatewaysdk/algorithm/gepa/lib/adapters/default_adapter/README.md +0 -0
  30. gatewaysdk/algorithm/gepa/lib/adapters/default_adapter/__init__.py +0 -0
  31. gatewaysdk/algorithm/gepa/lib/adapters/default_adapter/default_adapter.py +209 -0
  32. gatewaysdk/algorithm/gepa/lib/adapters/dspy_adapter/README.md +7 -0
  33. gatewaysdk/algorithm/gepa/lib/adapters/dspy_adapter/__init__.py +0 -0
  34. gatewaysdk/algorithm/gepa/lib/adapters/dspy_adapter/dspy_adapter.py +307 -0
  35. gatewaysdk/algorithm/gepa/lib/adapters/dspy_full_program_adapter/README.md +99 -0
  36. gatewaysdk/algorithm/gepa/lib/adapters/dspy_full_program_adapter/dspy_program_proposal_signature.py +137 -0
  37. gatewaysdk/algorithm/gepa/lib/adapters/dspy_full_program_adapter/full_program_adapter.py +268 -0
  38. gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/GEPA_RAG.md +621 -0
  39. gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/__init__.py +56 -0
  40. gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/evaluation_metrics.py +226 -0
  41. gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/generic_rag_adapter.py +496 -0
  42. gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/rag_pipeline.py +238 -0
  43. gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/vector_store_interface.py +212 -0
  44. gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/vector_stores/__init__.py +2 -0
  45. gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/vector_stores/chroma_store.py +196 -0
  46. gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/vector_stores/lancedb_store.py +422 -0
  47. gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/vector_stores/milvus_store.py +409 -0
  48. gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/vector_stores/qdrant_store.py +368 -0
  49. gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/vector_stores/weaviate_store.py +418 -0
  50. gatewaysdk/algorithm/gepa/lib/adapters/mcp_adapter/README.md +552 -0
  51. gatewaysdk/algorithm/gepa/lib/adapters/mcp_adapter/__init__.py +37 -0
  52. gatewaysdk/algorithm/gepa/lib/adapters/mcp_adapter/mcp_adapter.py +699 -0
  53. gatewaysdk/algorithm/gepa/lib/adapters/mcp_adapter/mcp_client.py +364 -0
  54. gatewaysdk/algorithm/gepa/lib/adapters/terminal_bench_adapter/README.md +9 -0
  55. gatewaysdk/algorithm/gepa/lib/adapters/terminal_bench_adapter/__init__.py +0 -0
  56. gatewaysdk/algorithm/gepa/lib/adapters/terminal_bench_adapter/terminal_bench_adapter.py +217 -0
  57. gatewaysdk/algorithm/gepa/lib/api.py +382 -0
  58. gatewaysdk/algorithm/gepa/lib/core/__init__.py +0 -0
  59. gatewaysdk/algorithm/gepa/lib/core/adapter.py +180 -0
  60. gatewaysdk/algorithm/gepa/lib/core/data_loader.py +74 -0
  61. gatewaysdk/algorithm/gepa/lib/core/engine.py +379 -0
  62. gatewaysdk/algorithm/gepa/lib/core/result.py +233 -0
  63. gatewaysdk/algorithm/gepa/lib/core/state.py +636 -0
  64. gatewaysdk/algorithm/gepa/lib/examples/__init__.py +0 -0
  65. gatewaysdk/algorithm/gepa/lib/examples/aime.py +24 -0
  66. gatewaysdk/algorithm/gepa/lib/examples/anymaths-bench/eval_default.py +111 -0
  67. gatewaysdk/algorithm/gepa/lib/examples/anymaths-bench/prompt-templates/instruction_prompt.txt +9 -0
  68. gatewaysdk/algorithm/gepa/lib/examples/anymaths-bench/prompt-templates/optimal_prompt.txt +24 -0
  69. gatewaysdk/algorithm/gepa/lib/examples/anymaths-bench/train_anymaths.py +177 -0
  70. gatewaysdk/algorithm/gepa/lib/examples/dspy_full_program_evolution/arc_agi.ipynb +25705 -0
  71. gatewaysdk/algorithm/gepa/lib/examples/dspy_full_program_evolution/example.ipynb +348 -0
  72. gatewaysdk/algorithm/gepa/lib/examples/mcp_adapter/__init__.py +4 -0
  73. gatewaysdk/algorithm/gepa/lib/examples/mcp_adapter/mcp_optimization_example.py +456 -0
  74. gatewaysdk/algorithm/gepa/lib/examples/rag_adapter/RAG_GUIDE.md +613 -0
  75. gatewaysdk/algorithm/gepa/lib/examples/rag_adapter/__init__.py +9 -0
  76. gatewaysdk/algorithm/gepa/lib/examples/rag_adapter/rag_optimization.py +820 -0
  77. gatewaysdk/algorithm/gepa/lib/examples/rag_adapter/requirements-rag.txt +29 -0
  78. gatewaysdk/algorithm/gepa/lib/examples/terminal-bench/prompt-templates/instruction_prompt.txt +16 -0
  79. gatewaysdk/algorithm/gepa/lib/examples/terminal-bench/prompt-templates/terminus.txt +9 -0
  80. gatewaysdk/algorithm/gepa/lib/examples/terminal-bench/train_terminus.py +161 -0
  81. gatewaysdk/algorithm/gepa/lib/gepa_utils.py +117 -0
  82. gatewaysdk/algorithm/gepa/lib/logging/__init__.py +0 -0
  83. gatewaysdk/algorithm/gepa/lib/logging/experiment_tracker.py +187 -0
  84. gatewaysdk/algorithm/gepa/lib/logging/logger.py +75 -0
  85. gatewaysdk/algorithm/gepa/lib/logging/utils.py +103 -0
  86. gatewaysdk/algorithm/gepa/lib/proposer/__init__.py +0 -0
  87. gatewaysdk/algorithm/gepa/lib/proposer/base.py +31 -0
  88. gatewaysdk/algorithm/gepa/lib/proposer/merge.py +357 -0
  89. gatewaysdk/algorithm/gepa/lib/proposer/reflective_mutation/__init__.py +0 -0
  90. gatewaysdk/algorithm/gepa/lib/proposer/reflective_mutation/base.py +49 -0
  91. gatewaysdk/algorithm/gepa/lib/proposer/reflective_mutation/reflective_mutation.py +176 -0
  92. gatewaysdk/algorithm/gepa/lib/py.typed +0 -0
  93. gatewaysdk/algorithm/gepa/lib/strategies/__init__.py +0 -0
  94. gatewaysdk/algorithm/gepa/lib/strategies/batch_sampler.py +77 -0
  95. gatewaysdk/algorithm/gepa/lib/strategies/candidate_selector.py +50 -0
  96. gatewaysdk/algorithm/gepa/lib/strategies/component_selector.py +36 -0
  97. gatewaysdk/algorithm/gepa/lib/strategies/eval_policy.py +64 -0
  98. gatewaysdk/algorithm/gepa/lib/strategies/instruction_proposal.py +126 -0
  99. gatewaysdk/algorithm/gepa/lib/utils/__init__.py +10 -0
  100. gatewaysdk/algorithm/gepa/lib/utils/stop_condition.py +196 -0
  101. gatewaysdk/algorithm/gepa/tracing.py +105 -0
  102. gatewaysdk/algorithm/utils.py +177 -0
  103. gatewaysdk/algorithm/verl/__init__.py +5 -0
  104. gatewaysdk/algorithm/verl/interface.py +202 -0
  105. gatewaysdk/automations.py +111 -0
  106. gatewaysdk/benchmark_hub/README.md +88 -0
  107. gatewaysdk/benchmark_hub/__init__.py +119 -0
  108. gatewaysdk/benchmark_hub/_archive.py +189 -0
  109. gatewaysdk/benchmark_hub/_tar.py +6 -0
  110. gatewaysdk/benchmark_hub/client.py +992 -0
  111. gatewaysdk/benchmark_hub/dispatch_shard.py +34 -0
  112. gatewaysdk/benchmark_hub/eval_config.py +20 -0
  113. gatewaysdk/benchmark_hub/evals.py +351 -0
  114. gatewaysdk/benchmark_hub/harbor_adapter.py +673 -0
  115. gatewaysdk/benchmark_hub/path_utils.py +81 -0
  116. gatewaysdk/benchmark_hub/save_utils.py +101 -0
  117. gatewaysdk/benchmark_hub/verifiers_adapter.py +327 -0
  118. gatewaysdk/benchmark_hub/versioning.py +72 -0
  119. gatewaysdk/build.py +515 -0
  120. gatewaysdk/cli/__init__.py +58 -0
  121. gatewaysdk/cli/agent_runner.py +132 -0
  122. gatewaysdk/cli/http_client.py +115 -0
  123. gatewaysdk/cli/platform.py +4086 -0
  124. gatewaysdk/cli/prometheus.py +115 -0
  125. gatewaysdk/cli/release_gate.py +215 -0
  126. gatewaysdk/cli/store.py +131 -0
  127. gatewaysdk/cli/vllm.py +29 -0
  128. gatewaysdk/client.py +406 -0
  129. gatewaysdk/config.py +348 -0
  130. gatewaysdk/connectors/__init__.py +25 -0
  131. gatewaysdk/connectors/client.py +203 -0
  132. gatewaysdk/connectors/skill.py +25 -0
  133. gatewaysdk/connectors/template.py +106 -0
  134. gatewaysdk/context.py +606 -0
  135. gatewaysdk/emitter/__init__.py +43 -0
  136. gatewaysdk/emitter/annotation.py +370 -0
  137. gatewaysdk/emitter/exception.py +54 -0
  138. gatewaysdk/emitter/message.py +61 -0
  139. gatewaysdk/emitter/object.py +117 -0
  140. gatewaysdk/emitter/reward.py +320 -0
  141. gatewaysdk/env_var.py +156 -0
  142. gatewaysdk/environment/__init__.py +108 -0
  143. gatewaysdk/environment/_bundle.py +281 -0
  144. gatewaysdk/environment/_harbor.py +276 -0
  145. gatewaysdk/environment/_materialize.py +97 -0
  146. gatewaysdk/environment/_tar.py +33 -0
  147. gatewaysdk/environment/_world.py +346 -0
  148. gatewaysdk/environment/core.py +527 -0
  149. gatewaysdk/environment/errors.py +58 -0
  150. gatewaysdk/environment/runtime.py +150 -0
  151. gatewaysdk/environment/schema/__init__.py +35 -0
  152. gatewaysdk/environment/schema/__main__.py +225 -0
  153. gatewaysdk/environment/schema/_slack_fidelity.py +116 -0
  154. gatewaysdk/environment/schema/_slack_scenario.py +183 -0
  155. gatewaysdk/environment/schema/api.py +1628 -0
  156. gatewaysdk/environment/schema/batch.py +755 -0
  157. gatewaysdk/environment/schema/compiler.py +615 -0
  158. gatewaysdk/environment/schema/conform.py +428 -0
  159. gatewaysdk/environment/schema/connector.py +777 -0
  160. gatewaysdk/environment/schema/connectors/apple-business-manager/handlers.py +17 -0
  161. gatewaysdk/environment/schema/connectors/apple-business-manager/parity.json +28 -0
  162. gatewaysdk/environment/schema/connectors/apple-business-manager/provenance.json +233 -0
  163. gatewaysdk/environment/schema/connectors/apple-business-manager/scope.toml +112 -0
  164. gatewaysdk/environment/schema/connectors/apple-business-manager/world.json +1380 -0
  165. gatewaysdk/environment/schema/connectors/base.json +28 -0
  166. gatewaysdk/environment/schema/connectors/custom/handlers.py +18 -0
  167. gatewaysdk/environment/schema/connectors/custom/world.json +123 -0
  168. gatewaysdk/environment/schema/connectors/github/handlers.py +81 -0
  169. gatewaysdk/environment/schema/connectors/github/parity.json +37 -0
  170. gatewaysdk/environment/schema/connectors/github/provenance.json +134 -0
  171. gatewaysdk/environment/schema/connectors/github/scope.toml +158 -0
  172. gatewaysdk/environment/schema/connectors/github/world.json +5869 -0
  173. gatewaysdk/environment/schema/connectors/google-calendar/handlers.py +23 -0
  174. gatewaysdk/environment/schema/connectors/google-calendar/world.json +209 -0
  175. gatewaysdk/environment/schema/connectors/google-drive/handlers.py +18 -0
  176. gatewaysdk/environment/schema/connectors/google-drive/world.json +286 -0
  177. gatewaysdk/environment/schema/connectors/jamf/handlers.py +34 -0
  178. gatewaysdk/environment/schema/connectors/jamf/parity.json +49 -0
  179. gatewaysdk/environment/schema/connectors/jamf/provenance.json +181 -0
  180. gatewaysdk/environment/schema/connectors/jamf/scope.toml +128 -0
  181. gatewaysdk/environment/schema/connectors/jamf/world.json +2218 -0
  182. gatewaysdk/environment/schema/connectors/jira/handlers.py +28 -0
  183. gatewaysdk/environment/schema/connectors/jira/world.json +389 -0
  184. gatewaysdk/environment/schema/connectors/kandji/handlers.py +38 -0
  185. gatewaysdk/environment/schema/connectors/kandji/parity.json +29 -0
  186. gatewaysdk/environment/schema/connectors/kandji/provenance.json +152 -0
  187. gatewaysdk/environment/schema/connectors/kandji/scope.toml +120 -0
  188. gatewaysdk/environment/schema/connectors/kandji/world.json +765 -0
  189. gatewaysdk/environment/schema/connectors/linear/handlers.py +20 -0
  190. gatewaysdk/environment/schema/connectors/linear/world.json +363 -0
  191. gatewaysdk/environment/schema/connectors/microsoft-teams/fidelity.json +45 -0
  192. gatewaysdk/environment/schema/connectors/microsoft-teams/handlers.py +1 -0
  193. gatewaysdk/environment/schema/connectors/microsoft-teams/provenance.json +851 -0
  194. gatewaysdk/environment/schema/connectors/microsoft-teams/scope.md +231 -0
  195. gatewaysdk/environment/schema/connectors/microsoft-teams/teams-types.json +1710 -0
  196. gatewaysdk/environment/schema/connectors/microsoft-teams/world.json +858 -0
  197. gatewaysdk/environment/schema/connectors/netsuite/handlers.py +32 -0
  198. gatewaysdk/environment/schema/connectors/netsuite/parity.json +50 -0
  199. gatewaysdk/environment/schema/connectors/netsuite/provenance.json +137 -0
  200. gatewaysdk/environment/schema/connectors/netsuite/scope.toml +78 -0
  201. gatewaysdk/environment/schema/connectors/netsuite/world.json +16243 -0
  202. gatewaysdk/environment/schema/connectors/salesforce/handlers.py +806 -0
  203. gatewaysdk/environment/schema/connectors/salesforce/parity.json +46 -0
  204. gatewaysdk/environment/schema/connectors/salesforce/provenance.json +143 -0
  205. gatewaysdk/environment/schema/connectors/salesforce/scope.toml +174 -0
  206. gatewaysdk/environment/schema/connectors/salesforce/world.json +4695 -0
  207. gatewaysdk/environment/schema/connectors/slack/MODEL.md +236 -0
  208. gatewaysdk/environment/schema/connectors/slack/capabilities.json +1039 -0
  209. gatewaysdk/environment/schema/connectors/slack/handlers.py +762 -0
  210. gatewaysdk/environment/schema/connectors/slack/parity.json +65 -0
  211. gatewaysdk/environment/schema/connectors/slack/provenance.json +294 -0
  212. gatewaysdk/environment/schema/connectors/slack/scope.toml +44 -0
  213. gatewaysdk/environment/schema/connectors/slack/world.json +4993 -0
  214. gatewaysdk/environment/schema/connectors/workday/handlers.py +75 -0
  215. gatewaysdk/environment/schema/connectors/workday/parity.json +36 -0
  216. gatewaysdk/environment/schema/connectors/workday/provenance.json +179 -0
  217. gatewaysdk/environment/schema/connectors/workday/scope.toml +180 -0
  218. gatewaysdk/environment/schema/connectors/workday/world.json +806 -0
  219. gatewaysdk/environment/schema/data.py +593 -0
  220. gatewaysdk/environment/schema/extract.py +263 -0
  221. gatewaysdk/environment/schema/host.py +2437 -0
  222. gatewaysdk/environment/schema/host_surfaces.py +275 -0
  223. gatewaysdk/environment/schema/platform.py +1272 -0
  224. gatewaysdk/environment/schema/scaffold.py +250 -0
  225. gatewaysdk/environment/schema/skill.py +118 -0
  226. gatewaysdk/environment/schema/skills/agents/connector-template-author.md +202 -0
  227. gatewaysdk/environment/schema/skills/connector-schema-authoring/CONNECTORS.md +331 -0
  228. gatewaysdk/environment/schema/skills/connector-schema-authoring/CONVENTIONS.md +100 -0
  229. gatewaysdk/environment/schema/skills/connector-schema-authoring/SKILL.md +313 -0
  230. gatewaysdk/environment/schema/skills/world-data-ingestion/ROWS.md +223 -0
  231. gatewaysdk/environment/schema/skills/world-data-ingestion/SKILL.md +293 -0
  232. gatewaysdk/environment/schema/skills/worlds-getting-started/SKILL.md +390 -0
  233. gatewaysdk/environment/schema/slack.py +757 -0
  234. gatewaysdk/environment/schema/snapshot.py +479 -0
  235. gatewaysdk/environment/schema/store.py +904 -0
  236. gatewaysdk/environment/schema/tasks.py +525 -0
  237. gatewaysdk/environment/schema/tools_world.py +322 -0
  238. gatewaysdk/environment/schema/validation.py +577 -0
  239. gatewaysdk/environment/schema/worker.py +78 -0
  240. gatewaysdk/environment/schema/workers.py +500 -0
  241. gatewaysdk/environment/schema/world_tests.py +336 -0
  242. gatewaysdk/environments/__init__.py +24 -0
  243. gatewaysdk/environments/client.py +486 -0
  244. gatewaysdk/environments/types.py +318 -0
  245. gatewaysdk/execution/__init__.py +15 -0
  246. gatewaysdk/execution/base.py +64 -0
  247. gatewaysdk/execution/client_server.py +443 -0
  248. gatewaysdk/execution/events.py +69 -0
  249. gatewaysdk/execution/inter_process.py +16 -0
  250. gatewaysdk/execution/shared_memory.py +282 -0
  251. gatewaysdk/experiments/__init__.py +90 -0
  252. gatewaysdk/experiments/assignment.py +177 -0
  253. gatewaysdk/experiments/client.py +877 -0
  254. gatewaysdk/experiments/exposure.py +222 -0
  255. gatewaysdk/experiments/types.py +81 -0
  256. gatewaysdk/importers/__init__.py +49 -0
  257. gatewaysdk/importers/_normalize.py +91 -0
  258. gatewaysdk/importers/builder.py +173 -0
  259. gatewaysdk/importers/client.py +95 -0
  260. gatewaysdk/importers/langsmith.py +196 -0
  261. gatewaysdk/importers/recipes.py +249 -0
  262. gatewaysdk/instrumentation/__init__.py +300 -0
  263. gatewaysdk/instrumentation/agentops.py +314 -0
  264. gatewaysdk/instrumentation/agentops_langchain.py +45 -0
  265. gatewaysdk/instrumentation/base.py +119 -0
  266. gatewaysdk/instrumentation/litellm.py +83 -0
  267. gatewaysdk/instrumentation/registry.py +273 -0
  268. gatewaysdk/instrumentation/vllm.py +81 -0
  269. gatewaysdk/instrumentation/weave.py +500 -0
  270. gatewaysdk/integrations/__init__.py +15 -0
  271. gatewaysdk/integrations/gateway/__init__.py +11 -0
  272. gatewaysdk/integrations/gateway/client.py +171 -0
  273. gatewaysdk/integrations/tool_access.py +549 -0
  274. gatewaysdk/litagent/__init__.py +11 -0
  275. gatewaysdk/litagent/decorator.py +536 -0
  276. gatewaysdk/litagent/litagent.py +252 -0
  277. gatewaysdk/llm_proxy.py +1742 -0
  278. gatewaysdk/logging.py +370 -0
  279. gatewaysdk/memory.py +278 -0
  280. gatewaysdk/personas.py +186 -0
  281. gatewaysdk/platform/__init__.py +17 -0
  282. gatewaysdk/platform/builder.py +221 -0
  283. gatewaysdk/platform/compatibility.py +67 -0
  284. gatewaysdk/platform/manifest.py +185 -0
  285. gatewaysdk/platform/orchestrator.py +901 -0
  286. gatewaysdk/platform/registry.py +122 -0
  287. gatewaysdk/platform/worker.py +864 -0
  288. gatewaysdk/replay/__init__.py +1032 -0
  289. gatewaysdk/replay/pytest.py +56 -0
  290. gatewaysdk/reward.py +7 -0
  291. gatewaysdk/run.py +1781 -0
  292. gatewaysdk/runner/__init__.py +11 -0
  293. gatewaysdk/runner/agent.py +878 -0
  294. gatewaysdk/runner/base.py +182 -0
  295. gatewaysdk/runner/legacy.py +309 -0
  296. gatewaysdk/security.py +700 -0
  297. gatewaysdk/semconv.py +170 -0
  298. gatewaysdk/server.py +399 -0
  299. gatewaysdk/sessions.py +282 -0
  300. gatewaysdk/store/__init__.py +45 -0
  301. gatewaysdk/store/base.py +908 -0
  302. gatewaysdk/store/client_server.py +2093 -0
  303. gatewaysdk/store/collection/__init__.py +30 -0
  304. gatewaysdk/store/collection/base.py +587 -0
  305. gatewaysdk/store/collection/memory.py +970 -0
  306. gatewaysdk/store/collection/mongo.py +1412 -0
  307. gatewaysdk/store/collection_based.py +1823 -0
  308. gatewaysdk/store/gateway.py +983 -0
  309. gatewaysdk/store/gateway_listener.py +465 -0
  310. gatewaysdk/store/listener.py +58 -0
  311. gatewaysdk/store/memory.py +396 -0
  312. gatewaysdk/store/mongo.py +165 -0
  313. gatewaysdk/store/redis_stream.py +517 -0
  314. gatewaysdk/store/sqlite.py +3 -0
  315. gatewaysdk/store/threading.py +370 -0
  316. gatewaysdk/store/utils.py +142 -0
  317. gatewaysdk/tracer/__init__.py +14 -0
  318. gatewaysdk/tracer/base.py +286 -0
  319. gatewaysdk/tracer/dummy.py +106 -0
  320. gatewaysdk/tracer/otel.py +559 -0
  321. gatewaysdk/tracing/__init__.py +110 -0
  322. gatewaysdk/tracing/api.py +808 -0
  323. gatewaysdk/tracing/attributes.py +9 -0
  324. gatewaysdk/tracing/context.py +272 -0
  325. gatewaysdk/tracing/exporters/__init__.py +10 -0
  326. gatewaysdk/tracing/exporters/gateway.py +228 -0
  327. gatewaysdk/tracing/identity.py +288 -0
  328. gatewaysdk/tracing/init.py +620 -0
  329. gatewaysdk/tracing/instrumentors/__init__.py +15 -0
  330. gatewaysdk/tracing/instrumentors/claude_agent_sdk.py +766 -0
  331. gatewaysdk/tracing/instrumentors/instrumentation_principles.md +294 -0
  332. gatewaysdk/tracing/instrumentors/registry.py +352 -0
  333. gatewaysdk/tracing/mapping.py +729 -0
  334. gatewaysdk/tracing/processors.py +393 -0
  335. gatewaysdk/tracing/push.py +617 -0
  336. gatewaysdk/tracing/push_models.py +247 -0
  337. gatewaysdk/tracing/semconv.py +294 -0
  338. gatewaysdk/tracing/span_builder.py +356 -0
  339. gatewaysdk/trainer/__init__.py +6 -0
  340. gatewaysdk/trainer/init_utils.py +263 -0
  341. gatewaysdk/trainer/legacy.py +359 -0
  342. gatewaysdk/trainer/registry.py +12 -0
  343. gatewaysdk/trainer/trainer.py +638 -0
  344. gatewaysdk/types/__init__.py +63 -0
  345. gatewaysdk/types/core.py +556 -0
  346. gatewaysdk/types/resources.py +204 -0
  347. gatewaysdk/types/tracer.py +515 -0
  348. gatewaysdk/types/tracing.py +162 -0
  349. gatewaysdk/users.py +251 -0
  350. gatewaysdk/utils/__init__.py +1 -0
  351. gatewaysdk/utils/id.py +18 -0
  352. gatewaysdk/utils/metrics.py +1025 -0
  353. gatewaysdk/utils/otel.py +550 -0
  354. gatewaysdk/utils/otlp.py +556 -0
  355. gatewaysdk/utils/redact.py +22 -0
  356. gatewaysdk/utils/server_launcher.py +1045 -0
  357. gatewaysdk/utils/system_snapshot.py +90 -0
  358. gatewaysdk/verl/__init__.py +8 -0
  359. gatewaysdk/verl/__main__.py +6 -0
  360. gatewaysdk/verl/async_server.py +46 -0
  361. gatewaysdk/verl/config.yaml +27 -0
  362. gatewaysdk/verl/daemon.py +1154 -0
  363. gatewaysdk/verl/dataset.py +44 -0
  364. gatewaysdk/verl/entrypoint.py +248 -0
  365. gatewaysdk/verl/trainer.py +549 -0
  366. gatewaysdk/world_browser.py +748 -0
  367. gatewaysdk/world_data.py +453 -0
  368. gatewaysdk/world_sessions.py +978 -0
  369. gatewaysdk/world_tasks.py +285 -0
  370. gatewaysdk/world_tools.py +115 -0
  371. gatewaysdk/worlds.py +639 -0
  372. gatewaysdk-0.3.2.dist-info/METADATA +236 -0
  373. gatewaysdk-0.3.2.dist-info/RECORD +376 -0
  374. gatewaysdk-0.3.2.dist-info/WHEEL +4 -0
  375. gatewaysdk-0.3.2.dist-info/entry_points.txt +5 -0
  376. gatewaysdk-0.3.2.dist-info/licenses/LICENSE +19 -0
@@ -0,0 +1,453 @@
1
+ """Rows into a platform world, in bulk: the client side of world data batches.
2
+
3
+ The wire is the platform's ``/api/public/worlds/{slug}/data`` routes (the contract,
4
+ section 7): open a batch, register each chunk by digest, PUT the chunk's bytes to
5
+ the presigned URL the platform hands back (or skip it when the platform already
6
+ holds that digest), mark it uploaded, complete the batch, poll it to a terminal
7
+ state. Auth and host resolution match the other clients: the project's public +
8
+ secret key as HTTP Basic (``GATEWAY_PUBLIC_KEY`` / ``GATEWAY_SECRET_KEY`` /
9
+ ``GATEWAY_HOST``). Standard library only.
10
+
11
+ :func:`import_rows` is the whole flow the CLI runs: rows streamed from files, cut
12
+ into gzipped chunks one at a time, uploaded ``parallel`` at a time, with a manifest
13
+ at ``.gateway/imports/<batchId>.json`` (section 10) written as each chunk lands so
14
+ ``--resume`` can pick the upload up where it stopped.
15
+ """
16
+
17
+ from __future__ import annotations
18
+
19
+ import base64
20
+ import json
21
+ import os
22
+ import sys
23
+ import tempfile
24
+ import threading
25
+ import time
26
+ import urllib.error
27
+ import urllib.parse
28
+ import urllib.request
29
+ from concurrent.futures import ThreadPoolExecutor
30
+ from dataclasses import dataclass
31
+ from datetime import datetime, timezone
32
+ from pathlib import Path
33
+ from typing import Any, Callable, Dict, Iterable, List, Optional
34
+
35
+ from gatewaysdk.environment.schema.batch import CHUNK_BYTES, Chunk, chunk_rows, iter_rows, write_report
36
+
37
+ MANIFEST_VERSION = 1
38
+ MANIFEST_DIR = Path(".gateway") / "imports"
39
+ TERMINAL = ("applied", "refused", "published", "failed")
40
+ RESUMABLE = ("open", "uploading")
41
+ POLL_SECONDS = 2.0
42
+ UPLOAD_TIMEOUT = 600
43
+
44
+
45
+ class WorldDataError(RuntimeError):
46
+ """Raised when any world data API call fails."""
47
+
48
+
49
+ # ---------------------------------------------------------------- the client
50
+
51
+
52
+ class WorldDataClient:
53
+ """Talks to a Gateway host's world data batch API."""
54
+
55
+ def __init__(self, host: str, public_key: str, secret_key: str) -> None:
56
+ if not host:
57
+ raise ValueError("host is required (e.g. https://withgateway.ai)")
58
+ if not public_key or not secret_key:
59
+ raise ValueError("both public_key and secret_key are required")
60
+ self.host = host.rstrip("/")
61
+ self._auth = base64.b64encode(f"{public_key}:{secret_key}".encode("utf-8")).decode("ascii")
62
+
63
+ @classmethod
64
+ def from_env(cls, host: Optional[str] = None) -> "WorldDataClient":
65
+ return cls(
66
+ host=host or os.environ.get("GATEWAY_HOST", ""),
67
+ public_key=os.environ.get("GATEWAY_PUBLIC_KEY", ""),
68
+ secret_key=os.environ.get("GATEWAY_SECRET_KEY", ""),
69
+ )
70
+
71
+ def request(self, method: str, path: str, body: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
72
+ headers = {"Authorization": f"Basic {self._auth}"}
73
+ data = None
74
+ if body is not None:
75
+ headers["Content-Type"] = "application/json"
76
+ data = json.dumps(body).encode("utf-8")
77
+ req = urllib.request.Request(f"{self.host}{path}", data=data, method=method, headers=headers)
78
+ try:
79
+ with urllib.request.urlopen(req, timeout=120) as resp:
80
+ text = resp.read().decode("utf-8")
81
+ return json.loads(text) if text else {}
82
+ except urllib.error.HTTPError as e:
83
+ detail = e.read().decode("utf-8", "replace")[:500]
84
+ raise WorldDataError(f"{method} {path} -> {e.code}: {detail}") from None
85
+ except urllib.error.URLError as e:
86
+ raise WorldDataError(f"{method} {path} -> {e.reason}") from None
87
+
88
+ @staticmethod
89
+ def route(slug: str) -> str:
90
+ return f"/api/public/worlds/{urllib.parse.quote(slug.split('@', 1)[0], safe='')}/data"
91
+
92
+ def open_batch(self, slug: str, **flags: Any) -> Dict[str, Any]:
93
+ return self.request("POST", f"{self.route(slug)}/batches", {k: v for k, v in flags.items() if v is not None})
94
+
95
+ def register_chunk(self, slug: str, batch_id: str, chunk: Dict[str, Any]) -> Dict[str, Any]:
96
+ return self.request("POST", f"{self.route(slug)}/batches/{batch_id}/chunks", chunk)
97
+
98
+ def mark_uploaded(self, slug: str, batch_id: str, chunk_id: str) -> Dict[str, Any]:
99
+ return self.request("POST", f"{self.route(slug)}/batches/{batch_id}/chunks/{chunk_id}/uploaded")
100
+
101
+ def complete(self, slug: str, batch_id: str) -> Dict[str, Any]:
102
+ return self.request("POST", f"{self.route(slug)}/batches/{batch_id}/complete")
103
+
104
+ def status(self, slug: str, batch_id: str) -> Dict[str, Any]:
105
+ return self.request("GET", f"{self.route(slug)}/batches/{batch_id}")
106
+
107
+ def batches(self, slug: str, *, limit: Optional[int] = None, cursor: Optional[str] = None) -> Dict[str, Any]:
108
+ query = urllib.parse.urlencode({k: v for k, v in (("limit", limit), ("cursor", cursor)) if v is not None})
109
+ return self.request("GET", f"{self.route(slug)}/batches" + (f"?{query}" if query else ""))
110
+
111
+ def publish(self, slug: str, message: Optional[str] = None) -> Dict[str, Any]:
112
+ return self.request("POST", f"{self.route(slug)}/publish", {"message": message} if message else {})
113
+
114
+ def counts(self, slug: str, entity: Optional[str] = None) -> Dict[str, Any]:
115
+ query = f"?entity={urllib.parse.quote(entity, safe='')}" if entity else ""
116
+ return self.request("GET", f"{self.route(slug)}{query}")
117
+
118
+ @staticmethod
119
+ def put_object(url: str, path: Path, size: int, headers: Optional[Dict[str, str]] = None) -> None:
120
+ """PUT a chunk's bytes to its presigned URL; no auth header, the URL is the grant.
121
+ ``headers`` are exactly the ones the platform signed the URL for (content-type,
122
+ content-length, x-amz-checksum-sha256); without them the plain pair is sent."""
123
+ signed = dict(headers) if headers else {"Content-Type": "application/gzip", "Content-Length": str(size)}
124
+ with open(path, "rb") as stream:
125
+ req = urllib.request.Request(url, data=stream, method="PUT", headers=signed)
126
+ try:
127
+ with urllib.request.urlopen(req, timeout=UPLOAD_TIMEOUT) as resp:
128
+ resp.read()
129
+ except urllib.error.HTTPError as e:
130
+ detail = e.read().decode("utf-8", "replace")[:300]
131
+ raise WorldDataError(f"chunk PUT -> {e.code}: {detail}") from None
132
+ except urllib.error.URLError as e:
133
+ raise WorldDataError(f"chunk PUT -> {e.reason}") from None
134
+
135
+ @staticmethod
136
+ def fetch_report(url: str) -> str:
137
+ try:
138
+ with urllib.request.urlopen(urllib.request.Request(url), timeout=120) as resp:
139
+ return resp.read().decode("utf-8")
140
+ except (urllib.error.HTTPError, urllib.error.URLError) as e:
141
+ raise WorldDataError(f"report download failed: {e}") from None
142
+
143
+
144
+ # ---------------------------------------------------------------- the manifest
145
+
146
+
147
+ def _now() -> str:
148
+ return datetime.now(timezone.utc).isoformat(timespec="seconds").replace("+00:00", "Z")
149
+
150
+
151
+ @dataclass
152
+ class Flags:
153
+ mode: str = "append"
154
+ merge: str = "upsert"
155
+ atomic: bool = True
156
+ publish: str = "now"
157
+ dryRun: bool = False
158
+ chunkBytes: int = CHUNK_BYTES
159
+ chunkRows: Optional[int] = None
160
+ entity: Optional[str] = None
161
+
162
+ def to_json(self) -> Dict[str, Any]:
163
+ return dict(self.__dict__)
164
+
165
+
166
+ class Manifest:
167
+ """``.gateway/imports/<batchId>.json``: what was uploaded, so a run can resume."""
168
+
169
+ def __init__(self, path: Path, data: Dict[str, Any]):
170
+ self.path = path
171
+ self.data = data
172
+ self._lock = threading.Lock()
173
+
174
+ @classmethod
175
+ def create(cls, base: Path, batch_id: str, slug: str, host: str, flags: Flags, inputs: List[str]) -> "Manifest":
176
+ directory = base / MANIFEST_DIR
177
+ directory.mkdir(parents=True, exist_ok=True)
178
+ ignore = base / ".gateway" / ".gitignore"
179
+ if not ignore.exists():
180
+ ignore.write_text("*\n")
181
+ manifest = cls(
182
+ directory / f"{batch_id}.json",
183
+ {
184
+ "version": MANIFEST_VERSION,
185
+ "batchId": batch_id,
186
+ "slug": slug,
187
+ "host": host,
188
+ "flags": flags.to_json(),
189
+ "inputs": list(inputs),
190
+ "chunks": [],
191
+ "completed": False,
192
+ "createdAt": _now(),
193
+ "updatedAt": _now(),
194
+ },
195
+ )
196
+ manifest.save()
197
+ return manifest
198
+
199
+ @classmethod
200
+ def load(cls, path: Path) -> "Manifest":
201
+ data = json.loads(path.read_text(encoding="utf-8"))
202
+ if data.get("version") != MANIFEST_VERSION:
203
+ raise WorldDataError(f"{path} is a manifest of version {data.get('version')}, not {MANIFEST_VERSION}")
204
+ return cls(path, data)
205
+
206
+ @classmethod
207
+ def find(cls, base: Path, slug: str, inputs: Optional[List[str]] = None) -> Optional["Manifest"]:
208
+ """The newest incomplete manifest for ``slug`` (and these inputs when given)."""
209
+ directory = base / MANIFEST_DIR
210
+ if not directory.is_dir():
211
+ return None
212
+ candidates = []
213
+ for path in directory.glob("*.json"):
214
+ try:
215
+ manifest = cls.load(path)
216
+ except (OSError, ValueError, WorldDataError):
217
+ continue
218
+ data = manifest.data
219
+ if data.get("completed") or data.get("slug") != slug.split("@", 1)[0]:
220
+ continue
221
+ if inputs is not None and data.get("inputs") != list(inputs):
222
+ continue
223
+ candidates.append(manifest)
224
+ if not candidates:
225
+ return None
226
+ return max(candidates, key=lambda m: m.data.get("updatedAt", ""))
227
+
228
+ @property
229
+ def batch_id(self) -> str:
230
+ return self.data["batchId"]
231
+
232
+ @property
233
+ def flags(self) -> Flags:
234
+ return Flags(**self.data["flags"])
235
+
236
+ def save(self) -> None:
237
+ with self._lock:
238
+ self.data["updatedAt"] = _now()
239
+ tmp = self.path.with_suffix(".json.tmp")
240
+ tmp.write_text(json.dumps(self.data, indent=1) + "\n", encoding="utf-8")
241
+ tmp.replace(self.path)
242
+
243
+ def record(self, entry: Dict[str, Any]) -> None:
244
+ with self._lock:
245
+ chunks = [c for c in self.data["chunks"] if c["ordinal"] != entry["ordinal"]]
246
+ chunks.append(entry)
247
+ self.data["chunks"] = sorted(chunks, key=lambda c: c["ordinal"])
248
+ self.save()
249
+
250
+ def uploaded(self, ordinal: int, digest: str) -> Optional[Dict[str, Any]]:
251
+ for entry in self.data["chunks"]:
252
+ if entry["ordinal"] == ordinal and entry["digest"] == digest and entry.get("uploaded"):
253
+ return entry
254
+ return None
255
+
256
+
257
+ # ---------------------------------------------------------------- the flow
258
+
259
+
260
+ Progress = Callable[[str], None]
261
+
262
+
263
+ def _quiet(_: str) -> None:
264
+ pass
265
+
266
+
267
+ def _upload(client: WorldDataClient, slug: str, batch_id: str, chunk: Chunk, manifest: Manifest) -> Dict[str, Any]:
268
+ entry = chunk.manifest_entry()
269
+ registered = client.register_chunk(
270
+ slug,
271
+ batch_id,
272
+ {
273
+ k: v
274
+ for k, v in (
275
+ ("ordinal", chunk.ordinal),
276
+ ("digest", chunk.digest),
277
+ ("bytes", chunk.bytes),
278
+ ("rows", chunk.rows),
279
+ ("entity", chunk.entity),
280
+ )
281
+ if v is not None
282
+ },
283
+ )
284
+ chunk_id = registered.get("chunkId")
285
+ entry["chunkId"] = chunk_id
286
+ if not registered.get("uploaded"):
287
+ url = registered.get("uploadUrl")
288
+ if not url:
289
+ raise WorldDataError(f"chunk {chunk.ordinal}: the platform gave neither uploaded nor an uploadUrl")
290
+ headers = registered.get("uploadHeaders")
291
+ if headers is not None and not (
292
+ isinstance(headers, dict) and all(isinstance(k, str) and isinstance(v, str) for k, v in headers.items())
293
+ ):
294
+ raise WorldDataError(f"chunk {chunk.ordinal}: uploadHeaders must map header names to strings")
295
+ client.put_object(url, chunk.path, chunk.bytes, headers)
296
+ client.mark_uploaded(slug, batch_id, chunk_id)
297
+ entry["uploaded"] = True
298
+ manifest.record(entry)
299
+ chunk.path.unlink(missing_ok=True)
300
+ return entry
301
+
302
+
303
+ def import_rows(
304
+ client: WorldDataClient,
305
+ slug: str,
306
+ inputs: List[str],
307
+ *,
308
+ flags: Flags,
309
+ parallel: int = 4,
310
+ resume: bool = False,
311
+ message: Optional[str] = None,
312
+ base: Optional[Path] = None,
313
+ progress: Progress = _quiet,
314
+ ) -> Manifest:
315
+ """Stream the rows files into chunks, upload them, complete the batch. Returns the
316
+ manifest; the caller polls the batch with :func:`wait`."""
317
+ base = base or Path.cwd()
318
+ manifest: Optional[Manifest] = None
319
+ if resume:
320
+ manifest = Manifest.find(base, slug, inputs)
321
+ if manifest is None:
322
+ raise WorldDataError(f"nothing to resume: no incomplete manifest for {slug} under {base / MANIFEST_DIR}")
323
+ state = client.status(slug, manifest.batch_id).get("state")
324
+ if state not in RESUMABLE:
325
+ raise WorldDataError(f"batch {manifest.batch_id} is {state}; only an open or uploading batch resumes")
326
+ flags = manifest.flags
327
+ progress(f"resuming batch {manifest.batch_id} ({len(manifest.data['chunks'])} chunks recorded)")
328
+ else:
329
+ opened = client.open_batch(
330
+ slug,
331
+ mode=flags.mode,
332
+ merge=flags.merge,
333
+ atomic=flags.atomic,
334
+ dryRun=flags.dryRun,
335
+ publish=flags.publish,
336
+ message=message,
337
+ )
338
+ batch_id = opened.get("batchId")
339
+ if not isinstance(batch_id, str) or not batch_id:
340
+ raise WorldDataError("the platform opened no batch (no batchId in the answer)")
341
+ limits = opened.get("limits") or {}
342
+ if isinstance(limits.get("chunkBytes"), int) and flags.chunkBytes > limits["chunkBytes"]:
343
+ raise WorldDataError(
344
+ f"--chunk-bytes {flags.chunkBytes} exceeds the platform's chunk limit {limits['chunkBytes']}"
345
+ )
346
+ manifest = Manifest.create(base, batch_id, slug.split("@", 1)[0], client.host, flags, inputs)
347
+ progress(f"batch {batch_id} open")
348
+ assert manifest is not None
349
+ batch_id = manifest.batch_id
350
+ errors: List[BaseException] = []
351
+ with tempfile.TemporaryDirectory(prefix="gateway-chunks-") as workdir:
352
+ with ThreadPoolExecutor(max_workers=max(1, parallel)) as pool:
353
+ pending = []
354
+ rows = iter_rows(inputs, entity=flags.entity)
355
+ for chunk in chunk_rows(
356
+ rows, workdir, chunk_bytes=flags.chunkBytes, chunk_rows=flags.chunkRows, entity=flags.entity
357
+ ):
358
+ if errors:
359
+ break
360
+ known = manifest.uploaded(chunk.ordinal, chunk.digest)
361
+ if known is not None:
362
+ progress(f"chunk {chunk.ordinal}: already uploaded ({chunk.rows} rows)")
363
+ chunk.path.unlink(missing_ok=True)
364
+ continue
365
+
366
+ def job(chunk: Chunk = chunk) -> None:
367
+ try:
368
+ entry = _upload(client, slug, batch_id, chunk, manifest)
369
+ progress(
370
+ f"chunk {chunk.ordinal}: uploaded {chunk.rows} rows, {chunk.bytes} bytes ({entry['chunkId']})"
371
+ )
372
+ except BaseException as error: # surfaced after the pool drains
373
+ errors.append(error)
374
+
375
+ pending.append(pool.submit(job))
376
+ # Bound the chunks on disk to the workers: the producer waits for a slot.
377
+ while sum(1 for f in pending if not f.done()) >= max(1, parallel):
378
+ time.sleep(0.05)
379
+ for future in pending:
380
+ future.result()
381
+ if errors:
382
+ raise errors[0]
383
+ client.complete(slug, batch_id)
384
+ manifest.data["completed"] = True
385
+ manifest.save()
386
+ progress(f"batch {batch_id} complete: {len(manifest.data['chunks'])} chunks")
387
+ return manifest
388
+
389
+
390
+ def wait(
391
+ client: WorldDataClient,
392
+ slug: str,
393
+ batch_id: str,
394
+ *,
395
+ progress: Progress = _quiet,
396
+ poll: float = POLL_SECONDS,
397
+ timeout: Optional[float] = None,
398
+ ) -> Dict[str, Any]:
399
+ """Poll the batch until a terminal state, one progress line per phase change."""
400
+ started = time.monotonic()
401
+ last = None
402
+ while True:
403
+ status = client.status(slug, batch_id)
404
+ phase = (status.get("state"), (status.get("progress") or {}).get("phase"))
405
+ if phase != last:
406
+ last = phase
407
+ detail = status.get("progress") or {}
408
+ progress(f"{status.get('state')}" + (f" ({detail.get('phase')})" if detail.get("phase") else ""))
409
+ if status.get("state") in TERMINAL:
410
+ return status
411
+ if timeout is not None and time.monotonic() - started > timeout:
412
+ return status
413
+ time.sleep(poll)
414
+
415
+
416
+ def write_status_report(client: WorldDataClient, status: Dict[str, Any], destination: Path) -> int:
417
+ """The batch's refusals as a JSONL report: the full report when the platform
418
+ offers one, else the records the status carries."""
419
+ url = status.get("reportUrl")
420
+ if url:
421
+ destination.write_text(client.fetch_report(url), encoding="utf-8")
422
+ return int(status.get("refusalCount") or 0)
423
+ records: Iterable[dict] = status.get("refusals") or []
424
+ with open(destination, "w", encoding="utf-8") as out:
425
+ return write_report(records, out)
426
+
427
+
428
+ def tty_progress(stream: Any = None) -> Progress:
429
+ """Progress lines on a TTY; silence otherwise."""
430
+ stream = stream or sys.stderr
431
+ if not hasattr(stream, "isatty") or not stream.isatty():
432
+ return _quiet
433
+
434
+ def show(line: str) -> None:
435
+ print(line, file=stream, flush=True)
436
+
437
+ return show
438
+
439
+
440
+ __all__ = [
441
+ "Flags",
442
+ "MANIFEST_DIR",
443
+ "MANIFEST_VERSION",
444
+ "Manifest",
445
+ "RESUMABLE",
446
+ "TERMINAL",
447
+ "WorldDataClient",
448
+ "WorldDataError",
449
+ "import_rows",
450
+ "tty_progress",
451
+ "wait",
452
+ "write_status_report",
453
+ ]