mostlyright-data 0.9.0__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 (314) hide show
  1. mostlyright/data_harness/__init__.py +158 -0
  2. mostlyright/data_harness/acquisition/__init__.py +55 -0
  3. mostlyright/data_harness/acquisition/http.py +2773 -0
  4. mostlyright/data_harness/acquisition/parsing.py +809 -0
  5. mostlyright/data_harness/acquisition/ranges.py +495 -0
  6. mostlyright/data_harness/acquisition/result_download.py +360 -0
  7. mostlyright/data_harness/acquisition/retention_admission.py +248 -0
  8. mostlyright/data_harness/acquisition/sandbox.py +4888 -0
  9. mostlyright/data_harness/acquisition/url_policy.py +530 -0
  10. mostlyright/data_harness/agent_runtime.py +2743 -0
  11. mostlyright/data_harness/assets/logo-ink.svg +31 -0
  12. mostlyright/data_harness/backends/__init__.py +28 -0
  13. mostlyright/data_harness/backends/pandas_backend.py +350 -0
  14. mostlyright/data_harness/backends/polars_backend.py +366 -0
  15. mostlyright/data_harness/backends/protocol.py +124 -0
  16. mostlyright/data_harness/backends/reference.py +83 -0
  17. mostlyright/data_harness/backends/registry.py +55 -0
  18. mostlyright/data_harness/backends/restrictions.py +126 -0
  19. mostlyright/data_harness/canonical.py +333 -0
  20. mostlyright/data_harness/catalog_job.py +625 -0
  21. mostlyright/data_harness/cli.py +5398 -0
  22. mostlyright/data_harness/contracts.py +53 -0
  23. mostlyright/data_harness/coordinator.py +1307 -0
  24. mostlyright/data_harness/deploy.py +924 -0
  25. mostlyright/data_harness/deploy_target.py +312 -0
  26. mostlyright/data_harness/deployment_evidence.py +1067 -0
  27. mostlyright/data_harness/event_presentation.py +576 -0
  28. mostlyright/data_harness/events.py +2152 -0
  29. mostlyright/data_harness/fast_delimited.py +239 -0
  30. mostlyright/data_harness/fleet.py +237 -0
  31. mostlyright/data_harness/formats.py +236 -0
  32. mostlyright/data_harness/governors.py +1163 -0
  33. mostlyright/data_harness/hosted_bootstrap.py +972 -0
  34. mostlyright/data_harness/hosted_crawler.py +1115 -0
  35. mostlyright/data_harness/hosted_crawler_container_smoke.py +351 -0
  36. mostlyright/data_harness/hosted_crawler_fetch.py +423 -0
  37. mostlyright/data_harness/hosted_crawler_job.py +1277 -0
  38. mostlyright/data_harness/hosted_crawler_protocol.py +676 -0
  39. mostlyright/data_harness/hosted_dataset.py +1500 -0
  40. mostlyright/data_harness/hosted_deploy.py +3037 -0
  41. mostlyright/data_harness/hosted_handoff.py +62 -0
  42. mostlyright/data_harness/hosted_ingestion_contract.py +504 -0
  43. mostlyright/data_harness/hosted_ingestion_job.py +356 -0
  44. mostlyright/data_harness/hosted_ingestion_job_smoke.py +40 -0
  45. mostlyright/data_harness/hosted_session_container_smoke.py +194 -0
  46. mostlyright/data_harness/hosted_session_worker.py +3554 -0
  47. mostlyright/data_harness/hosted_session_worker_job_smoke.py +46 -0
  48. mostlyright/data_harness/hosted_worker.py +6784 -0
  49. mostlyright/data_harness/ingestion/__init__.py +56 -0
  50. mostlyright/data_harness/ingestion/contracts.py +461 -0
  51. mostlyright/data_harness/ingestion/faults.py +42 -0
  52. mostlyright/data_harness/ingestion/gcs_store.py +1162 -0
  53. mostlyright/data_harness/ingestion/spool.py +130 -0
  54. mostlyright/data_harness/ingestion/store.py +885 -0
  55. mostlyright/data_harness/key_seam.py +434 -0
  56. mostlyright/data_harness/linux_process_boundary.py +262 -0
  57. mostlyright/data_harness/local_contracts.py +2880 -0
  58. mostlyright/data_harness/local_search/__init__.py +5 -0
  59. mostlyright/data_harness/local_search/build_index.py +1087 -0
  60. mostlyright/data_harness/local_search/contracts.py +920 -0
  61. mostlyright/data_harness/local_search/query_trace.py +266 -0
  62. mostlyright/data_harness/local_search/retrieval.py +700 -0
  63. mostlyright/data_harness/local_search/sealed.py +474 -0
  64. mostlyright/data_harness/local_search/service.py +784 -0
  65. mostlyright/data_harness/nbrender/CONTRACT.md +212 -0
  66. mostlyright/data_harness/nbrender/__init__.py +12 -0
  67. mostlyright/data_harness/nbrender/chrome.py +359 -0
  68. mostlyright/data_harness/nbrender/code_body.py +266 -0
  69. mostlyright/data_harness/nbrender/document.py +407 -0
  70. mostlyright/data_harness/nbrender/frame.py +275 -0
  71. mostlyright/data_harness/nbrender/interactive.py +337 -0
  72. mostlyright/data_harness/nbrender/markdown_body.py +477 -0
  73. mostlyright/data_harness/nbrender/mr_components.py +134 -0
  74. mostlyright/data_harness/nbrender/outputs_data.py +595 -0
  75. mostlyright/data_harness/nbrender/outputs_rich.py +906 -0
  76. mostlyright/data_harness/nbrender/outputs_source.py +260 -0
  77. mostlyright/data_harness/nbrender/outputs_stage.py +176 -0
  78. mostlyright/data_harness/nbrender/outputs_text.py +400 -0
  79. mostlyright/data_harness/nbrender/parse.py +394 -0
  80. mostlyright/data_harness/nbrender/status.py +40 -0
  81. mostlyright/data_harness/nbrender/tokens.py +1295 -0
  82. mostlyright/data_harness/notebook.py +1710 -0
  83. mostlyright/data_harness/offline.py +2049 -0
  84. mostlyright/data_harness/operation_registry.py +1007 -0
  85. mostlyright/data_harness/operator_setup.py +239 -0
  86. mostlyright/data_harness/pipeline.py +6428 -0
  87. mostlyright/data_harness/plan_graph.py +2026 -0
  88. mostlyright/data_harness/preparation/__init__.py +104 -0
  89. mostlyright/data_harness/preparation/contracts.py +1017 -0
  90. mostlyright/data_harness/preparation/engine.py +221 -0
  91. mostlyright/data_harness/preparation/errors.py +14 -0
  92. mostlyright/data_harness/preparation/gates.py +751 -0
  93. mostlyright/data_harness/preparation/joins.py +574 -0
  94. mostlyright/data_harness/preparation/profile.py +384 -0
  95. mostlyright/data_harness/preparation/table.py +217 -0
  96. mostlyright/data_harness/preparation/transforms.py +568 -0
  97. mostlyright/data_harness/progress_events.py +534 -0
  98. mostlyright/data_harness/readers/__init__.py +46 -0
  99. mostlyright/data_harness/readers/containers.py +963 -0
  100. mostlyright/data_harness/readers/contracts.py +542 -0
  101. mostlyright/data_harness/readers/delimited.py +257 -0
  102. mostlyright/data_harness/readers/grib2/__init__.py +33 -0
  103. mostlyright/data_harness/readers/grib2/admission.py +722 -0
  104. mostlyright/data_harness/readers/grib2/decode.py +1009 -0
  105. mostlyright/data_harness/readers/grib2/geometry.py +1133 -0
  106. mostlyright/data_harness/readers/grib2/portable_math.py +501 -0
  107. mostlyright/data_harness/readers/json_tabular.py +485 -0
  108. mostlyright/data_harness/readers/registry.py +514 -0
  109. mostlyright/data_harness/readers/samples/README.md +110 -0
  110. mostlyright/data_harness/readers/samples/archive.gzip/1.0.0/cities_one_stream/cities.csv.gz +0 -0
  111. mostlyright/data_harness/readers/samples/archive.gzip/1.0.0/cities_one_stream/expected.json +24 -0
  112. mostlyright/data_harness/readers/samples/archive.gzip/1.1.0/cities_one_stream/cities.csv.gz +0 -0
  113. mostlyright/data_harness/readers/samples/archive.gzip/1.1.0/cities_one_stream/expected.json +24 -0
  114. mostlyright/data_harness/readers/samples/archive.tar/1.0.0/cities_beside_a_directory_entry/cities.tar +0 -0
  115. mostlyright/data_harness/readers/samples/archive.tar/1.0.0/cities_beside_a_directory_entry/expected.json +24 -0
  116. mostlyright/data_harness/readers/samples/archive.tar/1.1.0/cities_beside_a_directory_entry/cities.tar +0 -0
  117. mostlyright/data_harness/readers/samples/archive.tar/1.1.0/cities_beside_a_directory_entry/expected.json +24 -0
  118. mostlyright/data_harness/readers/samples/archive.zip/1.0.0/cities_beside_a_second_member/cities.zip +0 -0
  119. mostlyright/data_harness/readers/samples/archive.zip/1.0.0/cities_beside_a_second_member/expected.json +25 -0
  120. mostlyright/data_harness/readers/samples/archive.zip/1.1.0/dwd_semicolon_station_member/dwd-station.zip +0 -0
  121. mostlyright/data_harness/readers/samples/archive.zip/1.1.0/dwd_semicolon_station_member/expected.json +25 -0
  122. mostlyright/data_harness/readers/samples/archive.zip/1.2.0/dwd_semicolon_station_member/dwd-station.zip +0 -0
  123. mostlyright/data_harness/readers/samples/archive.zip/1.2.0/dwd_semicolon_station_member/expected.json +25 -0
  124. mostlyright/data_harness/readers/samples/delimited_text/1.0.0/an_ordinary_comma_separated_table/cities.csv +3 -0
  125. mostlyright/data_harness/readers/samples/delimited_text/1.0.0/an_ordinary_comma_separated_table/expected.json +23 -0
  126. mostlyright/data_harness/readers/samples/delimited_text/1.0.0/quoted_fields_holding_the_delimiter/cities.tsv +5 -0
  127. mostlyright/data_harness/readers/samples/delimited_text/1.0.0/quoted_fields_holding_the_delimiter/expected.json +25 -0
  128. mostlyright/data_harness/readers/samples/delimited_text/1.1.0/an_hourly_observation_table_served_as_plain_text/expected.json +30 -0
  129. mostlyright/data_harness/readers/samples/delimited_text/1.1.0/an_hourly_observation_table_served_as_plain_text/observations.csv +5 -0
  130. mostlyright/data_harness/readers/samples/json.tabular/1.0.0/nested_hourly_observations/expected.json +44 -0
  131. mostlyright/data_harness/readers/samples/json.tabular/1.0.0/nested_hourly_observations/stations.json +1 -0
  132. mostlyright/data_harness/readers/samples/json.tabular/1.1.0/an_observation_stream_served_as_plain_text/expected.json +48 -0
  133. mostlyright/data_harness/readers/samples/json.tabular/1.1.0/an_observation_stream_served_as_plain_text/observations.ndjson +4 -0
  134. mostlyright/data_harness/readers/samples/spreadsheet.xlsx/1.0.0/an_ordinary_table_beside_a_second_sheet/cities.xlsx +0 -0
  135. mostlyright/data_harness/readers/samples/spreadsheet.xlsx/1.0.0/an_ordinary_table_beside_a_second_sheet/expected.json +24 -0
  136. mostlyright/data_harness/readers/samples/spreadsheet.xlsx/1.0.0/shares_the_workbook_had_already_computed/expected.json +27 -0
  137. mostlyright/data_harness/readers/samples/spreadsheet.xlsx/1.0.0/shares_the_workbook_had_already_computed/shares.xlsx +0 -0
  138. mostlyright/data_harness/readers/samples/spreadsheet.xlsx/1.1.0/shares_the_workbook_had_already_computed/expected.json +27 -0
  139. mostlyright/data_harness/readers/samples/spreadsheet.xlsx/1.1.0/shares_the_workbook_had_already_computed/shares.xlsx +0 -0
  140. mostlyright/data_harness/readers/samples/weather.grib2/1.0.0/README.md +20 -0
  141. mostlyright/data_harness/readers/samples/weather.grib2/1.0.0/gfs_2m_temperature/expected.json +55 -0
  142. mostlyright/data_harness/readers/samples/weather.grib2/1.0.0/gfs_2m_temperature/gfs-2m-temperature.grib2 +0 -0
  143. mostlyright/data_harness/readers/samples/weather.grib2/1.0.0/hrrr_2m_temperature/expected.json +54 -0
  144. mostlyright/data_harness/readers/samples/weather.grib2/1.0.0/hrrr_2m_temperature/hrrr-2m-temperature.grib2 +0 -0
  145. mostlyright/data_harness/readers/samples/weather.grib2/1.0.0/hrrr_categorical_rain/expected.json +54 -0
  146. mostlyright/data_harness/readers/samples/weather.grib2/1.0.0/hrrr_categorical_rain/hrrr-categorical-rain.grib2 +0 -0
  147. mostlyright/data_harness/readers/samples/weather.grib2/2.0.0/hrrr_2m_temperature/expected.json +54 -0
  148. mostlyright/data_harness/readers/samples/weather.grib2/2.0.0/hrrr_2m_temperature/hrrr-2m-temperature.grib2 +0 -0
  149. mostlyright/data_harness/readers/samples.py +582 -0
  150. mostlyright/data_harness/readers/spreadsheet.py +803 -0
  151. mostlyright/data_harness/readers/tabular.py +510 -0
  152. mostlyright/data_harness/recipe.py +5321 -0
  153. mostlyright/data_harness/repair/__init__.py +78 -0
  154. mostlyright/data_harness/repair/adapters.py +274 -0
  155. mostlyright/data_harness/repair/contracts.py +872 -0
  156. mostlyright/data_harness/repair/coordinator.py +1099 -0
  157. mostlyright/data_harness/repair/errors.py +16 -0
  158. mostlyright/data_harness/review.py +2533 -0
  159. mostlyright/data_harness/rowset.py +283 -0
  160. mostlyright/data_harness/serving.py +1975 -0
  161. mostlyright/data_harness/serving_edge.py +590 -0
  162. mostlyright/data_harness/serving_http.py +1031 -0
  163. mostlyright/data_harness/session_probes.py +759 -0
  164. mostlyright/data_harness/signing.py +101 -0
  165. mostlyright/data_harness/source_discovery.py +898 -0
  166. mostlyright/data_harness/sources/__init__.py +209 -0
  167. mostlyright/data_harness/sources/_adapter_steps.py +213 -0
  168. mostlyright/data_harness/sources/adapters.py +1214 -0
  169. mostlyright/data_harness/sources/cadence.py +1428 -0
  170. mostlyright/data_harness/sources/cadence_emission.py +453 -0
  171. mostlyright/data_harness/sources/cadence_history.py +546 -0
  172. mostlyright/data_harness/sources/catalog/__init__.py +17 -0
  173. mostlyright/data_harness/sources/catalog/admission.py +477 -0
  174. mostlyright/data_harness/sources/catalog/authoring.py +1701 -0
  175. mostlyright/data_harness/sources/catalog/authoring_policy.py +701 -0
  176. mostlyright/data_harness/sources/catalog/authoring_shards.py +1217 -0
  177. mostlyright/data_harness/sources/catalog/bounded_io.py +231 -0
  178. mostlyright/data_harness/sources/catalog/channel.py +523 -0
  179. mostlyright/data_harness/sources/catalog/channel_client.py +296 -0
  180. mostlyright/data_harness/sources/catalog/contracts.py +825 -0
  181. mostlyright/data_harness/sources/catalog/coverage.py +137 -0
  182. mostlyright/data_harness/sources/catalog/delta.py +1340 -0
  183. mostlyright/data_harness/sources/catalog/embedding.py +532 -0
  184. mostlyright/data_harness/sources/catalog/entry_v2.py +1182 -0
  185. mostlyright/data_harness/sources/catalog/fill.py +3889 -0
  186. mostlyright/data_harness/sources/catalog/fill_partitions.py +459 -0
  187. mostlyright/data_harness/sources/catalog/fill_staging.py +1105 -0
  188. mostlyright/data_harness/sources/catalog/gating.py +374 -0
  189. mostlyright/data_harness/sources/catalog/generation_receipt.py +1607 -0
  190. mostlyright/data_harness/sources/catalog/harvest/__init__.py +7 -0
  191. mostlyright/data_harness/sources/catalog/harvest/ckan.py +384 -0
  192. mostlyright/data_harness/sources/catalog/harvest/datagov_v4.py +798 -0
  193. mostlyright/data_harness/sources/catalog/harvest/protocol.py +964 -0
  194. mostlyright/data_harness/sources/catalog/harvest/sdmx.py +445 -0
  195. mostlyright/data_harness/sources/catalog/harvest/stac.py +384 -0
  196. mostlyright/data_harness/sources/catalog/health.py +447 -0
  197. mostlyright/data_harness/sources/catalog/hosted_catalog.py +105 -0
  198. mostlyright/data_harness/sources/catalog/identity_history.py +1549 -0
  199. mostlyright/data_harness/sources/catalog/neural.py +1618 -0
  200. mostlyright/data_harness/sources/catalog/packed_catalog.py +2345 -0
  201. mostlyright/data_harness/sources/catalog/packed_retrieval.py +1517 -0
  202. mostlyright/data_harness/sources/catalog/packed_writer.py +2802 -0
  203. mostlyright/data_harness/sources/catalog/query_trace.py +1037 -0
  204. mostlyright/data_harness/sources/catalog/recommend.py +171 -0
  205. mostlyright/data_harness/sources/catalog/retrieval.py +230 -0
  206. mostlyright/data_harness/sources/catalog/retrieval_manifest.py +995 -0
  207. mostlyright/data_harness/sources/catalog/rights_decisions.py +254 -0
  208. mostlyright/data_harness/sources/catalog/sealed.py +560 -0
  209. mostlyright/data_harness/sources/catalog/search.py +230 -0
  210. mostlyright/data_harness/sources/catalog/streaming_delta.py +1097 -0
  211. mostlyright/data_harness/sources/catalog/update.py +891 -0
  212. mostlyright/data_harness/sources/collections.py +815 -0
  213. mostlyright/data_harness/sources/contracts.py +2223 -0
  214. mostlyright/data_harness/sources/deletion.py +761 -0
  215. mostlyright/data_harness/sources/fitness.py +162 -0
  216. mostlyright/data_harness/sources/governance.py +163 -0
  217. mostlyright/data_harness/sources/hosted.py +173 -0
  218. mostlyright/data_harness/sources/integration.py +218 -0
  219. mostlyright/data_harness/sources/range_reader.py +418 -0
  220. mostlyright/data_harness/sources/registry.py +514 -0
  221. mostlyright/data_harness/sources/rights_rule.py +59 -0
  222. mostlyright/data_harness/sources/source_cadence_vectors.v1.json +1 -0
  223. mostlyright/data_harness/sources/sports.py +521 -0
  224. mostlyright/data_harness/sources/stream.py +524 -0
  225. mostlyright/data_harness/sources/stream_connector.py +418 -0
  226. mostlyright/data_harness/sources/stream_recorder.py +1404 -0
  227. mostlyright/data_harness/studio_boundary.py +2019 -0
  228. mostlyright/data_harness/thin/__init__.py +37 -0
  229. mostlyright/data_harness/thin/acquire.py +1137 -0
  230. mostlyright/data_harness/thin/acquire_cancel.py +579 -0
  231. mostlyright/data_harness/thin/approvals.py +617 -0
  232. mostlyright/data_harness/thin/commands.py +406 -0
  233. mostlyright/data_harness/thin/download.py +194 -0
  234. mostlyright/data_harness/thin/narrative.py +589 -0
  235. mostlyright/data_harness/thin/parity.py +1070 -0
  236. mostlyright/data_harness/thin/propose.py +2759 -0
  237. mostlyright/data_harness/thin/research.py +1663 -0
  238. mostlyright/data_harness/thin/router.py +924 -0
  239. mostlyright/data_harness/thin/runs.py +519 -0
  240. mostlyright/data_harness/thin/session.py +281 -0
  241. mostlyright/data_harness/thin/stream.py +501 -0
  242. mostlyright/data_harness/thin/transport.py +187 -0
  243. mostlyright/data_harness/thin/vocabulary.py +368 -0
  244. mostlyright/data_harness/thin/workers.py +164 -0
  245. mostlyright/data_harness/ucum/TABLE-PIN.json +40 -0
  246. mostlyright/data_harness/ucum/ucum-subset.v1.json +632 -0
  247. mostlyright/data_harness/unit_flow.py +927 -0
  248. mostlyright/data_harness/units.py +572 -0
  249. mostlyright/data_harness/ux/__init__.py +9 -0
  250. mostlyright/data_harness/ux/approve.py +485 -0
  251. mostlyright/data_harness/ux/author_yaml.py +597 -0
  252. mostlyright/data_harness/ux/cloud_auth.py +447 -0
  253. mostlyright/data_harness/ux/commands/__init__.py +260 -0
  254. mostlyright/data_harness/ux/commands/approve.py +136 -0
  255. mostlyright/data_harness/ux/commands/auth.py +744 -0
  256. mostlyright/data_harness/ux/commands/author.py +79 -0
  257. mostlyright/data_harness/ux/commands/catalog_author.py +403 -0
  258. mostlyright/data_harness/ux/commands/catalog_fill.py +523 -0
  259. mostlyright/data_harness/ux/commands/catalog_harvest.py +545 -0
  260. mostlyright/data_harness/ux/commands/catalog_publish.py +1838 -0
  261. mostlyright/data_harness/ux/commands/catalog_search.py +71 -0
  262. mostlyright/data_harness/ux/commands/catalog_update.py +437 -0
  263. mostlyright/data_harness/ux/commands/deploy.py +134 -0
  264. mostlyright/data_harness/ux/commands/deploy_dataset.py +98 -0
  265. mostlyright/data_harness/ux/commands/deploy_plan.py +105 -0
  266. mostlyright/data_harness/ux/commands/deploy_status.py +104 -0
  267. mostlyright/data_harness/ux/commands/diff.py +74 -0
  268. mostlyright/data_harness/ux/commands/index.py +84 -0
  269. mostlyright/data_harness/ux/commands/inventory.py +47 -0
  270. mostlyright/data_harness/ux/commands/list_builds.py +143 -0
  271. mostlyright/data_harness/ux/commands/login.py +63 -0
  272. mostlyright/data_harness/ux/commands/peek.py +236 -0
  273. mostlyright/data_harness/ux/commands/plan_check.py +90 -0
  274. mostlyright/data_harness/ux/commands/preflight.py +97 -0
  275. mostlyright/data_harness/ux/commands/record.py +107 -0
  276. mostlyright/data_harness/ux/commands/review_setup.py +47 -0
  277. mostlyright/data_harness/ux/commands/search.py +440 -0
  278. mostlyright/data_harness/ux/commands/show.py +61 -0
  279. mostlyright/data_harness/ux/commands/whoami.py +37 -0
  280. mostlyright/data_harness/ux/credential_native.py +551 -0
  281. mostlyright/data_harness/ux/credential_store.py +1055 -0
  282. mostlyright/data_harness/ux/credentials.py +631 -0
  283. mostlyright/data_harness/ux/diffing.py +444 -0
  284. mostlyright/data_harness/ux/headline.py +671 -0
  285. mostlyright/data_harness/ux/hosted_acquisition.py +974 -0
  286. mostlyright/data_harness/ux/hosted_run_status.py +619 -0
  287. mostlyright/data_harness/ux/inventory.py +427 -0
  288. mostlyright/data_harness/ux/local_review.py +375 -0
  289. mostlyright/data_harness/ux/login.py +691 -0
  290. mostlyright/data_harness/ux/path_kind.py +147 -0
  291. mostlyright/data_harness/ux/peek.py +1000 -0
  292. mostlyright/data_harness/ux/plain_file.py +178 -0
  293. mostlyright/data_harness/ux/plan_check.py +311 -0
  294. mostlyright/data_harness/ux/preflight.py +918 -0
  295. mostlyright/data_harness/ux/readers.py +1124 -0
  296. mostlyright/data_harness/ux/remediation.py +2195 -0
  297. mostlyright/data_harness/ux/render.py +657 -0
  298. mostlyright/data_harness/ux/workload.py +1077 -0
  299. mostlyright/data_harness/viewer.py +3713 -0
  300. mostlyright/data_harness/visual_run/__init__.py +83 -0
  301. mostlyright/data_harness/visual_run/authoring.py +235 -0
  302. mostlyright/data_harness/visual_run/contracts.py +673 -0
  303. mostlyright/data_harness/visual_run/materialize.py +486 -0
  304. mostlyright/data_harness/visual_run/observations.py +874 -0
  305. mostlyright/data_harness/visual_run/query.py +259 -0
  306. mostlyright/data_harness/visual_run/reducer.py +280 -0
  307. mostlyright/data_harness/visual_run/sdk.py +892 -0
  308. mostlyright/data_harness/visual_run/store.py +584 -0
  309. mostlyright/data_harness/visual_run/transport.py +239 -0
  310. mostlyright/data_harness/watch.py +2999 -0
  311. mostlyright_data-0.9.0.dist-info/METADATA +607 -0
  312. mostlyright_data-0.9.0.dist-info/RECORD +314 -0
  313. mostlyright_data-0.9.0.dist-info/WHEEL +4 -0
  314. mostlyright_data-0.9.0.dist-info/entry_points.txt +12 -0
@@ -0,0 +1,79 @@
1
+ """``mr-data author`` -- write the Recipe in YAML, get the Recipe you can approve.
2
+
3
+ Three gates stand between the file a person writes and the fingerprint `mr-data approve` binds:
4
+ the reader refuses rather than guesses, `parse_fresh_recipe` checks the result against the
5
+ contract field by field and resolves every Reader pin, and the written file is created without
6
+ overwriting anything.
7
+
8
+ This module is the command and nothing else. The reading lives in
9
+ :mod:`mostlyright.data_harness.ux.author_yaml`, so the same step is available to a browser page
10
+ without going through argparse. Nothing here prints, and nothing here catches a refusal: the
11
+ command line renders it with the sentences the remediation map supplies.
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ import argparse
17
+ from pathlib import Path
18
+ from typing import Any
19
+
20
+ from mostlyright.data_harness.canonical import canonical_json_bytes
21
+ from mostlyright.data_harness.recipe import RecipeError, parse_fresh_recipe
22
+ from mostlyright.data_harness.ux.author_yaml import parse_author_yaml, read_author_source
23
+ from mostlyright.data_harness.ux.commands import CommandSpec
24
+
25
+
26
+ def add_arguments(parser: argparse.ArgumentParser) -> None:
27
+ # The flag names match recipe-export deliberately: a person who knows one knows the other.
28
+ parser.add_argument(
29
+ "--recipe",
30
+ type=Path,
31
+ required=True,
32
+ help="the YAML file you wrote the Recipe in",
33
+ )
34
+ parser.add_argument(
35
+ "--output",
36
+ type=Path,
37
+ required=True,
38
+ help="where to write the Recipe; nothing is ever overwritten",
39
+ )
40
+
41
+
42
+ def run(args: argparse.Namespace) -> dict[str, Any]:
43
+ # Imported here, not at the top: this package is loaded while the command line is still being
44
+ # set up. Reusing the command line's own writer is what keeps this file's publication receipt
45
+ # identical to the one every other written output carries.
46
+ from mostlyright.data_harness import cli
47
+
48
+ recipe = parse_fresh_recipe(parse_author_yaml(read_author_source(args.recipe)))
49
+ raw = canonical_json_bytes(recipe.to_dict())
50
+ try:
51
+ publication = cli._write_output_exclusive(
52
+ args.output,
53
+ raw,
54
+ purpose="recipe",
55
+ authority="stdout_recipe_receipt",
56
+ )
57
+ except FileExistsError as exc:
58
+ raise RecipeError(
59
+ "RECIPE_OUTPUT_EXISTS",
60
+ "output",
61
+ "recipe output already exists",
62
+ ) from exc
63
+ return {
64
+ "status": "recipe_authored",
65
+ "output": str(args.output),
66
+ "recipe_id": recipe.recipe_id,
67
+ "recipe_version": recipe.recipe_version,
68
+ "recipe_digest": recipe.digest,
69
+ "expected_size_bytes": len(raw),
70
+ "publication": publication,
71
+ }
72
+
73
+
74
+ SPEC = CommandSpec(
75
+ name="author",
76
+ help="turn a YAML recipe description into a recipe you can approve",
77
+ add_arguments=add_arguments,
78
+ run=run,
79
+ )
@@ -0,0 +1,403 @@
1
+ """``catalog-author``: stream one converged v4 generation into bounded authoring shards.
2
+
3
+ This module is the explicit second stage of the provider-scale harvest -> author -> publish
4
+ workflow. It reads a private staging root and an exact harvest receipt, and writes immutable
5
+ authoring shards behind one atomic manifest plus one secret-free receipt. It reaches no network,
6
+ accepts no key material, opens no predecessor catalog, and never loads a whole generation into
7
+ memory; every one of those properties is a structural consequence of what it imports.
8
+
9
+ A ``--resume`` may replace only the exact typed-incomplete receipt its interrupted run left at the
10
+ same path, after checking that the retained receipt belongs to this stage and describes this
11
+ output root. A fresh receipt path remains exclusive, and a complete receipt is never overwritten.
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ import argparse
17
+ from collections.abc import Mapping
18
+ from pathlib import Path
19
+ from typing import Any
20
+
21
+ from mostlyright.data_harness.canonical import (
22
+ CanonicalJSONError,
23
+ parse_canonical_json,
24
+ sha256_bytes,
25
+ )
26
+ from mostlyright.data_harness.sources.catalog.authoring_shards import (
27
+ AUTHORING_RECEIPT_SCHEMA,
28
+ MAX_AUTHORING_SHARD_BYTES,
29
+ MAX_AUTHORING_SHARD_ENTRIES,
30
+ AuthoringLimits,
31
+ AuthoringSelection,
32
+ CatalogAuthoringRefused,
33
+ run_catalog_authoring,
34
+ )
35
+ from mostlyright.data_harness.sources.catalog.bounded_io import (
36
+ BoundedReadFailure,
37
+ read_bounded_path,
38
+ )
39
+ from mostlyright.data_harness.sources.catalog.coverage import (
40
+ COVERAGE_EXHAUSTIVE_RULE,
41
+ SELECTION_RULES,
42
+ )
43
+ from mostlyright.data_harness.sources.catalog.generation_receipt import (
44
+ ReceiptInstallation,
45
+ install_receipt,
46
+ load_execution_coordinate,
47
+ publication_output_lock,
48
+ receipt_installation_lock,
49
+ require_output_root_identity,
50
+ retained_incomplete_receipt,
51
+ root_coordinate,
52
+ )
53
+ from mostlyright.data_harness.ux.commands import CommandSpec
54
+
55
+ # The exact stage receipts this command will accept as the source of a fill checkpoint digest.
56
+ # A receipt is a coordinate carrier, never an authority: the live staging checkpoint decides
57
+ # whether the generation converged.
58
+ HARVEST_RECEIPT_SCHEMAS = frozenset({"mr-data-catalog-fill.v1", "mr-data-catalog-harvest.v1"})
59
+ MAX_HARVEST_RECEIPT_BYTES = 8_388_608
60
+ MAX_AUTHOR_RECEIPT_BYTES = 8_388_608
61
+
62
+
63
+ def add_arguments(parser: argparse.ArgumentParser) -> None:
64
+ parser.add_argument(
65
+ "--staging-root",
66
+ type=Path,
67
+ required=True,
68
+ help="the private staging root holding one converged harvest generation",
69
+ )
70
+ parser.add_argument(
71
+ "--harvest-receipt",
72
+ type=Path,
73
+ required=True,
74
+ help="the exact harvest receipt naming the staging checkpoint to author",
75
+ )
76
+ parser.add_argument(
77
+ "--harvest-receipt-sha256", required=True, help="the exact harvest receipt fingerprint"
78
+ )
79
+ parser.add_argument(
80
+ "--policy", required=True, help="the exact reviewed authoring policy coordinate"
81
+ )
82
+ parser.add_argument(
83
+ "--output-root", type=Path, required=True, help="the authoring shard output root"
84
+ )
85
+ parser.add_argument(
86
+ "--receipt-file", type=Path, required=True, help="where this stage's receipt is installed"
87
+ )
88
+ parser.add_argument(
89
+ "--execution-manifest",
90
+ type=Path,
91
+ help="the committed source and installed-wheel coordinate document",
92
+ )
93
+ parser.add_argument("--execution-commit", help="the exact commit that coordinate was cut at")
94
+ parser.add_argument(
95
+ "--max-records", type=int, required=True, help="maximum authored provider records"
96
+ )
97
+ parser.add_argument(
98
+ "--max-input-bytes", type=int, required=True, help="maximum normalized input bytes read"
99
+ )
100
+ parser.add_argument(
101
+ "--max-shard-entries",
102
+ type=int,
103
+ required=True,
104
+ help=f"entries per authoring shard, at most {MAX_AUTHORING_SHARD_ENTRIES}",
105
+ )
106
+ parser.add_argument(
107
+ "--max-shard-bytes",
108
+ type=int,
109
+ required=True,
110
+ help=f"bytes per authoring shard, at most {MAX_AUTHORING_SHARD_BYTES}",
111
+ )
112
+ parser.add_argument(
113
+ "--max-disk-bytes", type=int, required=True, help="maximum local working disk bytes"
114
+ )
115
+ parser.add_argument(
116
+ "--max-wall-seconds", type=int, required=True, help="maximum cumulative authoring seconds"
117
+ )
118
+ parser.add_argument(
119
+ "--coverage-rule",
120
+ choices=sorted(SELECTION_RULES),
121
+ default=None,
122
+ help=(
123
+ "the registered rule that selects a bounded part of the converged sweep; "
124
+ "omit both coverage flags to author every record the sweep found"
125
+ ),
126
+ )
127
+ parser.add_argument(
128
+ "--coverage-bound",
129
+ type=int,
130
+ default=None,
131
+ help=(
132
+ "how many records that rule selects. This is not --max-records: --max-records is a "
133
+ "resource budget whose exhaustion still yields an incomplete generation, so set it "
134
+ "at least as large as this bound or the run stops at AUTHOR_RECORD_LIMIT"
135
+ ),
136
+ )
137
+ parser.add_argument(
138
+ "--resume",
139
+ action="store_true",
140
+ help="continue the retained partial generation from its exact journal digest",
141
+ )
142
+
143
+
144
+ def run(args: argparse.Namespace) -> dict[str, Any]:
145
+ output_root = Path(args.output_root)
146
+ with publication_output_lock(
147
+ output_root,
148
+ label="output_root",
149
+ code_prefix="AUTHOR",
150
+ refusal=CatalogAuthoringRefused,
151
+ ) as output_descriptor:
152
+ with receipt_installation_lock(
153
+ args.receipt_file,
154
+ label="receipt_file",
155
+ code_prefix="AUTHOR",
156
+ refusal=CatalogAuthoringRefused,
157
+ ) as receipt_installation:
158
+ return _run_locked(
159
+ args,
160
+ output_root=output_root,
161
+ output_descriptor=output_descriptor,
162
+ receipt_installation=receipt_installation,
163
+ )
164
+
165
+
166
+ def _run_locked(
167
+ args: argparse.Namespace,
168
+ *,
169
+ output_root: Path,
170
+ output_descriptor: int,
171
+ receipt_installation: ReceiptInstallation,
172
+ ) -> dict[str, Any]:
173
+ manifest_path = getattr(args, "execution_manifest", None)
174
+ execution_commit = getattr(args, "execution_commit", None)
175
+ if (manifest_path is None) != (execution_commit is None):
176
+ raise CatalogAuthoringRefused(
177
+ "AUTHOR_EXECUTION_COORDINATE",
178
+ "execution_manifest",
179
+ "execution manifest and commit are supplied together",
180
+ )
181
+ execution = (
182
+ None
183
+ if manifest_path is None
184
+ else load_execution_coordinate(Path(manifest_path), execution_commit)
185
+ )
186
+ checkpoint_sha256, harvest_execution = _harvest_checkpoint(
187
+ args.harvest_receipt, args.harvest_receipt_sha256
188
+ )
189
+ if harvest_execution is not None and execution != harvest_execution:
190
+ raise CatalogAuthoringRefused(
191
+ "AUTHOR_EXECUTION_COORDINATE",
192
+ "execution_manifest",
193
+ "provider-scale authoring must execute the exact harvest coordinate",
194
+ )
195
+ selection = _selection(args)
196
+ replaces = _replaceable_receipt(
197
+ Path(args.receipt_file), output_root, resume=args.resume, execution=execution
198
+ )
199
+ expected_journal_sha256 = None
200
+ if args.resume:
201
+ expected_journal_sha256 = _retained_journal_sha256(output_root)
202
+ result = run_catalog_authoring(
203
+ staging_root=Path(args.staging_root),
204
+ expected_fill_checkpoint_sha256=checkpoint_sha256,
205
+ policy_id=args.policy,
206
+ output_root=output_root,
207
+ limits=AuthoringLimits(
208
+ max_records=args.max_records,
209
+ max_input_bytes=args.max_input_bytes,
210
+ max_shard_entries=args.max_shard_entries,
211
+ max_shard_bytes=args.max_shard_bytes,
212
+ max_disk_bytes=args.max_disk_bytes,
213
+ max_wall_seconds=args.max_wall_seconds,
214
+ ),
215
+ selection=selection,
216
+ expected_journal_sha256=expected_journal_sha256,
217
+ output_descriptor=output_descriptor,
218
+ )
219
+ payload = {
220
+ **result.receipt,
221
+ "harvest_receipt_sha256": args.harvest_receipt_sha256,
222
+ "output_root_sha256": root_coordinate(output_root),
223
+ }
224
+ if execution is not None:
225
+ payload["execution"] = execution
226
+
227
+ def commit_guard() -> None:
228
+ require_output_root_identity(
229
+ output_root,
230
+ output_descriptor,
231
+ label="output_root",
232
+ code_prefix="AUTHOR",
233
+ refusal=CatalogAuthoringRefused,
234
+ )
235
+
236
+ install_receipt(
237
+ Path(args.receipt_file),
238
+ payload,
239
+ maximum=MAX_AUTHOR_RECEIPT_BYTES,
240
+ label="receipt_file",
241
+ code_prefix="AUTHOR",
242
+ refusal=CatalogAuthoringRefused,
243
+ replaces=replaces,
244
+ installation=receipt_installation,
245
+ commit_guard=commit_guard,
246
+ )
247
+ return payload
248
+
249
+
250
+ def _selection(args: argparse.Namespace) -> AuthoringSelection:
251
+ """The coverage this invocation was asked for, stated by two flags or by neither.
252
+
253
+ Both flags or neither: a rule without a bound does not say how much of the sweep to take,
254
+ and a bound without a rule does not say which records, so each alone is an instruction this
255
+ command cannot carry out. Refusing here rather than picking a default for the missing half
256
+ keeps an operator from discovering at publication that they published a catalogue nobody
257
+ asked for.
258
+
259
+ The default is exhaustive, which is what this command did before a bound could be stated.
260
+ That direction matters: forgetting a flag can only publish a whole catalogue, never a
261
+ silently partial one.
262
+ """
263
+
264
+ rule = getattr(args, "coverage_rule", None)
265
+ bound = getattr(args, "coverage_bound", None)
266
+ if rule is None and bound is None:
267
+ return AuthoringSelection()
268
+ if rule is None or bound is None:
269
+ raise CatalogAuthoringRefused(
270
+ "AUTHOR_COVERAGE",
271
+ "coverage_rule",
272
+ "a bounded coverage states its rule and its bound together",
273
+ )
274
+ if rule == COVERAGE_EXHAUSTIVE_RULE:
275
+ raise CatalogAuthoringRefused(
276
+ "AUTHOR_COVERAGE",
277
+ "coverage_rule",
278
+ "an exhaustive coverage is what omitting both flags asks for",
279
+ )
280
+ return AuthoringSelection(rule=rule, bound=bound)
281
+
282
+
283
+ def _replaceable_receipt(
284
+ path: Path,
285
+ output_root: Path,
286
+ *,
287
+ resume: bool,
288
+ execution: Mapping[str, Any] | None = None,
289
+ ) -> dict[str, Any] | None:
290
+ """The typed-incomplete receipt this resume is allowed to replace, or nothing at all.
291
+
292
+ Installation is otherwise ``O_EXCL``: evidence is never overwritten. The one exception is the
293
+ receipt an interrupted invocation of *this* stage left at *this* destination for *this* output
294
+ root, which the resume that continues it replaces rather than leaving two documents describing
295
+ one generation.
296
+ """
297
+
298
+ if not resume:
299
+ return None
300
+ retained = retained_incomplete_receipt(
301
+ path,
302
+ maximum=MAX_AUTHOR_RECEIPT_BYTES,
303
+ label="receipt_file",
304
+ schema=AUTHORING_RECEIPT_SCHEMA,
305
+ incomplete_status="incomplete",
306
+ output_root=output_root,
307
+ code_prefix="AUTHOR",
308
+ refusal=CatalogAuthoringRefused,
309
+ )
310
+ if retained is not None and retained.get("execution") != execution:
311
+ raise CatalogAuthoringRefused(
312
+ "AUTHOR_RESUME_RECEIPT",
313
+ "execution_manifest",
314
+ "the retained authoring stage used another execution coordinate",
315
+ )
316
+ return retained
317
+
318
+
319
+ def _harvest_checkpoint(path: Path, expected_sha256: Any) -> tuple[str, Mapping[str, Any] | None]:
320
+ if not _is_digest(expected_sha256):
321
+ raise CatalogAuthoringRefused(
322
+ "AUTHOR_HARVEST_RECEIPT_DIGEST",
323
+ "harvest_receipt_sha256",
324
+ "must be a lowercase SHA-256",
325
+ )
326
+ raw = _read_bounded_regular(path, maximum=MAX_HARVEST_RECEIPT_BYTES)
327
+ if sha256_bytes(raw) != expected_sha256:
328
+ raise CatalogAuthoringRefused(
329
+ "AUTHOR_HARVEST_RECEIPT_DIGEST",
330
+ "harvest_receipt",
331
+ "harvest receipt bytes differ from the required digest",
332
+ )
333
+ try:
334
+ payload = parse_canonical_json(raw)
335
+ except CanonicalJSONError as error:
336
+ raise CatalogAuthoringRefused(
337
+ "AUTHOR_HARVEST_RECEIPT_SCHEMA", "harvest_receipt", "receipt is not canonical JSON"
338
+ ) from error
339
+ if (
340
+ not isinstance(payload, Mapping)
341
+ or payload.get("schema_version") not in HARVEST_RECEIPT_SCHEMAS
342
+ or not _is_digest(payload.get("checkpoint_sha256"))
343
+ ):
344
+ raise CatalogAuthoringRefused(
345
+ "AUTHOR_HARVEST_RECEIPT_SCHEMA",
346
+ "harvest_receipt",
347
+ "receipt must name one accepted stage schema and an exact checkpoint digest",
348
+ )
349
+ execution = payload.get("execution")
350
+ if payload["schema_version"] == "mr-data-catalog-harvest.v1":
351
+ if not isinstance(execution, Mapping):
352
+ raise CatalogAuthoringRefused(
353
+ "AUTHOR_HARVEST_RECEIPT_SCHEMA",
354
+ "harvest_receipt",
355
+ "provider-scale harvest receipt must carry its execution coordinate",
356
+ )
357
+ return payload["checkpoint_sha256"], execution
358
+ return payload["checkpoint_sha256"], None
359
+
360
+
361
+ def _retained_journal_sha256(output_root: Path) -> str:
362
+ raw = _read_bounded_regular(output_root / "journal.json", maximum=MAX_AUTHOR_RECEIPT_BYTES)
363
+ return sha256_bytes(raw)
364
+
365
+
366
+ def _read_bounded_regular(path: Path, *, maximum: int) -> bytes:
367
+ try:
368
+ raw = read_bounded_path(path, maximum=maximum)
369
+ except (BoundedReadFailure, OSError) as error:
370
+ if isinstance(error, OSError):
371
+ raise CatalogAuthoringRefused(
372
+ "AUTHOR_INPUT_UNREADABLE", str(path.name), "cannot open the required document"
373
+ ) from error
374
+ if error.reason not in {"limit", "type", "changed"}:
375
+ raise CatalogAuthoringRefused(
376
+ "AUTHOR_INPUT_UNREADABLE", str(path.name), "cannot open the required document"
377
+ ) from error
378
+ raise CatalogAuthoringRefused(
379
+ "AUTHOR_INPUT_LIMIT",
380
+ str(path.name),
381
+ "must be a stable bounded single-link regular file",
382
+ ) from error
383
+ assert raw is not None
384
+ return raw
385
+
386
+
387
+ def _is_digest(value: Any) -> bool:
388
+ return (
389
+ isinstance(value, str) and len(value) == 64 and all(c in "0123456789abcdef" for c in value)
390
+ )
391
+
392
+
393
+ def _exit_code(payload: Mapping[str, Any]) -> int:
394
+ return 0 if payload.get("status") == "complete" else 1
395
+
396
+
397
+ SPEC = CommandSpec(
398
+ name="catalog-author",
399
+ help="author one converged public catalog generation into bounded authoring shards",
400
+ add_arguments=add_arguments,
401
+ run=run,
402
+ exit_code=_exit_code,
403
+ )