mostlyright-data 0.26.0__tar.gz → 0.26.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/PKG-INFO +1 -1
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/pyproject.toml +1 -1
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/readers.md +1 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/sources.md +5 -1
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/recipe.py +29 -38
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/recipe_explain.py +114 -52
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/recipe_lint.py +71 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/v4.py +1 -1
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/.gitignore +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/README.md +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/scripts/hatch_build.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/SKILL.md +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/agents/openai.yaml +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/1-open-the-page-and-the-link-to-it-in-the-first-message.md +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/2-brief-two-to-four-questions-each-with-a-recommended-answer.md +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/3-probe-read-a-source-before-committing-to-it.md +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/4-decide-say-what-you-chose-what-you-refused-and-ask-one-question.md +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/5-draft-one-recipe-document-one-call.md +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/6-build-one-run-sized-to-acquire-every-measured-source-whole.md +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/7-interrogate-ask-the-run-what-it-actually-delivered.md +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/8-fix-revise-the-document-and-register-it-again.md +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/9-present-only-what-survived-inspection-with-caveats.md +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/agent-protocol.md +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/autonomous-delivery.md +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/before-the-first-tool-call.md +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/boundaries.md +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/cloud-authentication-preflight.md +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/commands.md +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/cross-repository-protocol-reference.md +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/installation-parity.md +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/live-run.md +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/making-a-table-incremental.md +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/narrating-the-run.md +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/not-hosted-yet.md +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/one-install.md +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/prediction-labels.md +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/promote.md +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/receipts.md +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/recording-a-stream-venue.md +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/recovering-an-import-failure.md +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/reference-pages.md +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/required-protocol.md +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/source-credentials.md +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/the-one-thing-to-say-about-the-skill-itself.md +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/transforms.md +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/user-communication-contract.md +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/writing-a-decision-record.md +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/scripts/write_research_notebook.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/__init__.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/agent_protocol.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/canonical.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/formats.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/hosted_crawler_protocol.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/key_seam.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/page_coverage.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/part_check_evidence.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/session_probes.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/skill_assets.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/table_manifest.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/__init__.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/acquire.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/acquire_cancel.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/activity.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/approvals.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/categories.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/commands.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/dataset-categories-v1.json +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/download.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/narrative.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/parity.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/probe.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/progress_vocabulary.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/propose.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/recipe_brief.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/recipe_forecast.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/research.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/router.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/run_diagnose.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/runs.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/session.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/stream.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/stream_venue.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/studio_capabilities.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/transport.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/user_agent.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/v4_artifacts.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/v4_catalog.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/v4_connected.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/v4_connections.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/v4_dataset_covers.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/v4_datasets.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/v4_handoff.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/v4_narrative.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/v4_public.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/v4_query.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/v4_reader.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/v4_runs.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/v4_secrets.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/v4_stream.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/v4_tables.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/vocabulary.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/ux/__init__.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/ux/attendance.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/ux/clarification.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/ux/cloud_auth.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/ux/commands/__init__.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/ux/commands/auth.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/ux/commands/clarify.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/ux/commands/login.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/ux/commands/whoami.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/ux/credential_native.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/ux/credential_store.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/ux/credentials.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/ux/login.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/ux/path_kind.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/ux/plain_file.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/ux/remediation.py +0 -0
- {mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/ux/render.py +0 -0
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/readers.md
RENAMED
|
@@ -90,6 +90,7 @@ decoder. Zero matches and multiple matches both refuse.
|
|
|
90
90
|
| `delimited_text@2.0.0` | Explicit delimiter, encoding, quoting, header presence, skip_rows, skip_blank_rows, and indexed columns with output names and optional expected_header; unselected_columns requires empty cells unless explicitly set to allow. |
|
|
91
91
|
| `json.tabular@1.0.0` | `columns` with output names and RFC 6901 pointers; optional `document_format` (`json` or `ndjson`), `records_pointer`, and sequential `expand` pointers. Columns are required unless they state `required: false`. |
|
|
92
92
|
| `json.tabular@1.1.0` | Same; also accepts a response served as `text/plain` (common for public agency JSON and NDJSON). |
|
|
93
|
+
| `json.tabular@1.2.0` | Same as 1.1.0. An `expand` entry may be `{"pointer": "/x", "required": false}`. A record whose array there is null, missing or too short adds no rows instead of refusing the document. A present member that is not an array still refuses. |
|
|
93
94
|
| `xml.tabular@1.0.0` | Absolute record element path, declared namespace prefixes, and relative field selectors ending in `text()` or `@attribute`; fields are required unless `required: false`. |
|
|
94
95
|
| `html.tabular@1.0.0` | Absolute record element path and relative text/attribute field selectors; fields are required unless `required: false`. |
|
|
95
96
|
| `html.web_extract@1.0.0` | `mode: dom` with closed CSS-like record/field selectors, or `mode: json` with an inert JSON script selector and RFC 6901 field pointers. |
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/sources.md
RENAMED
|
@@ -190,6 +190,8 @@ Write the request by these rules.
|
|
|
190
190
|
- `method` is `GET` or `POST`. A `POST` states `body_template`, and a `GET` states none.
|
|
191
191
|
- Each `{name}` placeholder takes the upstream row's cell in the column of that name.
|
|
192
192
|
- Every placeholder is a declared parameter, and every parameter is used.
|
|
193
|
+
- A literal brace is written twice, `{{` or `}}`. Any other brace is refused. A SPARQL query can
|
|
194
|
+
ride in a query value this way.
|
|
193
195
|
- Every parameter and every entry of `carry_columns` is a column of the upstream source.
|
|
194
196
|
- A header value is a literal. The worker writes `Content-Type` itself.
|
|
195
197
|
- Every literal the request sends is printable ASCII, with no trailing newline.
|
|
@@ -251,7 +253,9 @@ and a redirect. A keyless 401 or 403 is one of them. Tell the user each run fail
|
|
|
251
253
|
and one sentence.
|
|
252
254
|
|
|
253
255
|
When the upstream source has a request window, the collection inherits it. Name the window's
|
|
254
|
-
`merge.partition.column` in `carry_columns`, or registration refuses the recipe. A
|
|
256
|
+
`merge.partition.column` in `carry_columns`, or registration refuses the recipe. A per-row
|
|
257
|
+
request collection over another per-row request collection inherits the same window when every
|
|
258
|
+
hop carries that column. `mr-data recipe explain` names each hop that drops it. A refresh then
|
|
255
259
|
sends requests only for rows in the refreshed partitions. A request the predecessor answered
|
|
256
260
|
successfully is never sent again, whatever the row's carried cells or partition now are. A full
|
|
257
261
|
build leaves out an upstream row whose partition cell does not read. Read this source alone in the
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/recipe.py
RENAMED
|
@@ -478,55 +478,45 @@ def _named_source(source: Mapping[str, Any], index: int) -> str:
|
|
|
478
478
|
def _inherits_a_direct_window(source: Mapping[str, Any], sources: Sequence[Any]) -> bool:
|
|
479
479
|
"""Whether this collection refreshes with a direct request window of the same recipe.
|
|
480
480
|
|
|
481
|
-
Studio's ``_inherits_a_direct_window``, read the way it reads it. The
|
|
482
|
-
``source_rows``
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
every
|
|
487
|
-
|
|
488
|
-
|
|
481
|
+
Studio's ``_inherits_a_direct_window``, read the way it reads it. The collection is a per-row
|
|
482
|
+
request collection, a ``source_rows`` discovery that states ``request``, and its chain of
|
|
483
|
+
such collections up ``discovery.source`` (:func:`recipe_explain.inherited_window_chain`)
|
|
484
|
+
ends at a direct window of this plan: not a stream, not ``closed``, not a collection, with a
|
|
485
|
+
``window`` that carries ``request`` and no ``snapshot`` and replaces whole partitions. And
|
|
486
|
+
every hop, this collection included, names that window's ``merge.partition.column`` in
|
|
487
|
+
``request.carry_columns``, so every member is keyed to its upstream row's partition and a
|
|
488
|
+
refresh re-derives exactly the members of the partitions the window replaces. A chain that
|
|
489
|
+
loops, or that passes a ``url_column`` collection, inherits nothing.
|
|
489
490
|
|
|
490
491
|
A name two sources share is nobody's upstream here. That document is malformed, and the
|
|
491
492
|
refusal for it is the registration route's.
|
|
492
493
|
"""
|
|
493
494
|
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
if not isinstance(request, Mapping) or not isinstance(upstream_name, str):
|
|
501
|
-
return False
|
|
502
|
-
upstreams = [
|
|
503
|
-
candidate
|
|
495
|
+
counted: dict[str, int] = {}
|
|
496
|
+
for candidate in sources:
|
|
497
|
+
if isinstance(candidate, Mapping) and isinstance(candidate.get("name"), str):
|
|
498
|
+
counted[candidate["name"]] = counted.get(candidate["name"], 0) + 1
|
|
499
|
+
by_name = {
|
|
500
|
+
candidate["name"]: candidate
|
|
504
501
|
for candidate in sources
|
|
505
|
-
if isinstance(candidate, Mapping)
|
|
506
|
-
|
|
507
|
-
|
|
502
|
+
if isinstance(candidate, Mapping)
|
|
503
|
+
and isinstance(candidate.get("name"), str)
|
|
504
|
+
and counted[candidate["name"]] == 1
|
|
505
|
+
}
|
|
506
|
+
chain = recipe_explain.inherited_window_chain(source, by_name)
|
|
507
|
+
if chain is None:
|
|
508
508
|
return False
|
|
509
|
-
|
|
509
|
+
root, hops = chain
|
|
510
|
+
upstream = by_name[root]
|
|
510
511
|
if (
|
|
511
512
|
upstream.get("source_class") == "stream"
|
|
512
513
|
or upstream.get("closed") is True
|
|
513
514
|
or isinstance(upstream.get("collection"), Mapping)
|
|
514
515
|
):
|
|
515
516
|
return False
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
column = partition.get("column") if isinstance(partition, Mapping) else None
|
|
520
|
-
carried = request.get("carry_columns")
|
|
521
|
-
return (
|
|
522
|
-
isinstance(window, Mapping)
|
|
523
|
-
and "snapshot" not in window
|
|
524
|
-
and isinstance(window.get("request"), Mapping)
|
|
525
|
-
and isinstance(merge, Mapping)
|
|
526
|
-
and merge.get("materialization") == "partition_replace"
|
|
527
|
-
and isinstance(column, str)
|
|
528
|
-
and isinstance(carried, list)
|
|
529
|
-
and column in carried
|
|
517
|
+
column = recipe_explain.window_partition_column(upstream)
|
|
518
|
+
return column is not None and all(
|
|
519
|
+
column in recipe_explain.row_request_carried(hop) for hop in hops
|
|
530
520
|
)
|
|
531
521
|
|
|
532
522
|
|
|
@@ -730,8 +720,9 @@ def unrefreshable_plan_finding(
|
|
|
730
720
|
"collection restores its ledger from the raw snapshot and cannot join the "
|
|
731
721
|
"replacement-partition proof a refresh writes, so it refuses the whole table. The one "
|
|
732
722
|
"collection a refresh admits sends one request per row of a direct request window "
|
|
733
|
-
"in this recipe,
|
|
734
|
-
"that
|
|
723
|
+
"in this recipe, directly or through other such collections, each through a "
|
|
724
|
+
"`source_rows` discovery that states `request` and names that window's "
|
|
725
|
+
"`merge.partition.column` in `request.carry_columns`. "
|
|
735
726
|
f"{UNREFRESHABLE_PLAN_TAIL}"
|
|
736
727
|
)
|
|
737
728
|
if "window" in held:
|
|
@@ -493,34 +493,57 @@ def declared_rebuild(document: Mapping[str, Any]) -> Mapping[str, Any] | None:
|
|
|
493
493
|
return declaration
|
|
494
494
|
|
|
495
495
|
|
|
496
|
-
def
|
|
497
|
-
source: Mapping[str, Any],
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
carried by the request. A snapshot window, a closed source and another collection are none.
|
|
496
|
+
def inherited_window_chain(
|
|
497
|
+
source: Mapping[str, Any], sources: Mapping[str, Mapping[str, Any]]
|
|
498
|
+
) -> tuple[str, tuple[Mapping[str, Any], ...]] | None:
|
|
499
|
+
"""The source a per-row request chain reads its rows from, and every hop on the way.
|
|
500
|
+
|
|
501
|
+
Studio's rule: walk ``discovery.source`` through per-row request collections, starting at
|
|
502
|
+
``source``, until a source that is not one. Answers that source's name and every hop,
|
|
503
|
+
``source`` first, or ``None`` when ``source`` is no per-row request collection, a hop names an
|
|
504
|
+
undeclared source, or the chain loops back on itself.
|
|
506
505
|
"""
|
|
507
506
|
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
507
|
+
hops: list[Mapping[str, Any]] = []
|
|
508
|
+
visited: set[str] = set()
|
|
509
|
+
current = source
|
|
510
|
+
while True:
|
|
511
|
+
discovery = _row_discovery(current)
|
|
512
|
+
request = discovery.get("request") if discovery is not None else None
|
|
513
|
+
upstream = discovery.get("source") if discovery is not None else None
|
|
514
|
+
if not isinstance(request, Mapping) or not isinstance(upstream, str):
|
|
515
|
+
return None
|
|
516
|
+
hops.append(current)
|
|
517
|
+
following = sources.get(upstream)
|
|
518
|
+
if following is None or upstream in visited:
|
|
519
|
+
return None
|
|
520
|
+
visited.add(upstream)
|
|
521
|
+
following_discovery = _row_discovery(following)
|
|
522
|
+
if following_discovery is None or not isinstance(
|
|
523
|
+
following_discovery.get("request"), Mapping
|
|
524
|
+
):
|
|
525
|
+
return upstream, tuple(hops)
|
|
526
|
+
current = following
|
|
527
|
+
|
|
528
|
+
|
|
529
|
+
def row_request_carried(source: Mapping[str, Any]) -> tuple[str, ...]:
|
|
530
|
+
"""The columns a per-row request collection carries, or none for any other source."""
|
|
531
|
+
|
|
532
|
+
discovery = _row_discovery(source)
|
|
533
|
+
request = discovery.get("request") if discovery is not None else None
|
|
534
|
+
carried = request.get("carry_columns") if isinstance(request, Mapping) else None
|
|
535
|
+
if not isinstance(carried, list):
|
|
536
|
+
return ()
|
|
537
|
+
return tuple(name for name in carried if isinstance(name, str))
|
|
538
|
+
|
|
539
|
+
|
|
540
|
+
def window_partition_column(source: Mapping[str, Any]) -> str | None:
|
|
541
|
+
"""The partition column of a request window that replaces whole partitions, else ``None``."""
|
|
542
|
+
|
|
543
|
+
window = source.get("window")
|
|
520
544
|
merge = window.get("merge") if isinstance(window, Mapping) else None
|
|
521
545
|
partition = merge.get("partition") if isinstance(merge, Mapping) else None
|
|
522
|
-
|
|
523
|
-
return (
|
|
546
|
+
if (
|
|
524
547
|
isinstance(window, Mapping)
|
|
525
548
|
and "snapshot" not in window
|
|
526
549
|
and isinstance(window.get("request"), Mapping)
|
|
@@ -528,9 +551,30 @@ def _inherits_a_direct_window(
|
|
|
528
551
|
and merge.get("materialization") == "partition_replace"
|
|
529
552
|
and isinstance(partition, Mapping)
|
|
530
553
|
and isinstance(partition.get("column"), str)
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
554
|
+
):
|
|
555
|
+
return str(partition["column"])
|
|
556
|
+
return None
|
|
557
|
+
|
|
558
|
+
|
|
559
|
+
def _inherits_a_direct_window(
|
|
560
|
+
source: Mapping[str, Any],
|
|
561
|
+
sources: Mapping[str, Mapping[str, Any]],
|
|
562
|
+
direct_windows: Sequence[str],
|
|
563
|
+
) -> bool:
|
|
564
|
+
"""Whether this per-row request collection inherits a request window of this plan.
|
|
565
|
+
|
|
566
|
+
Studio's rule: the end of the per-row request chain (:func:`inherited_window_chain`) is a
|
|
567
|
+
direct window of the same plan that states ``request`` (not only ``snapshot``) and replaces
|
|
568
|
+
whole partitions, and every hop, this collection included, carries its partition column. A
|
|
569
|
+
snapshot window, a closed source, a ``url_column`` collection and a loop are none.
|
|
570
|
+
"""
|
|
571
|
+
|
|
572
|
+
chain = inherited_window_chain(source, sources)
|
|
573
|
+
if chain is None or chain[0] not in direct_windows:
|
|
574
|
+
return False
|
|
575
|
+
root, hops = chain
|
|
576
|
+
column = window_partition_column(sources[root])
|
|
577
|
+
return column is not None and all(column in row_request_carried(hop) for hop in hops)
|
|
534
578
|
|
|
535
579
|
|
|
536
580
|
def _layout_is_consistent(
|
|
@@ -573,9 +617,10 @@ def _not_inheriting(
|
|
|
573
617
|
upstream = discovery.get("source") if discovery is not None else None
|
|
574
618
|
if isinstance(upstream, str) and upstream in sources:
|
|
575
619
|
detail = (
|
|
576
|
-
f"{name} derives its rows from {upstream}, which is
|
|
577
|
-
f"replacing whole partitions
|
|
578
|
-
f"
|
|
620
|
+
f"{name} derives its rows from {upstream}, which is neither a request window "
|
|
621
|
+
f"replacing whole partitions nor a per-row request collection inheriting one, with "
|
|
622
|
+
f"that window's partition column carried by {name} and every collection between, so "
|
|
623
|
+
f"a refresh cannot tell which of its members changed"
|
|
579
624
|
)
|
|
580
625
|
else:
|
|
581
626
|
detail = (
|
|
@@ -927,37 +972,51 @@ def _rebuild(facts: _Facts) -> list[dict[str, Any]]:
|
|
|
927
972
|
|
|
928
973
|
|
|
929
974
|
def _collection_suggestions(names: Sequence[str], facts: _Facts) -> list[dict[str, Any]]:
|
|
975
|
+
"""What would let each collection inherit a request window of its own table.
|
|
976
|
+
|
|
977
|
+
A per-row request chain inherits the window its first non-collection upstream states, so the
|
|
978
|
+
window and the missing carries are judged at the end of the chain, not one hop up.
|
|
979
|
+
"""
|
|
980
|
+
|
|
981
|
+
by_name = {name: facts.source(name) for name in facts.indices}
|
|
930
982
|
suggestions: list[dict[str, Any]] = []
|
|
931
983
|
for name in names:
|
|
932
|
-
|
|
984
|
+
source = facts.source(name)
|
|
985
|
+
discovery = _row_discovery(source) or {}
|
|
933
986
|
upstream_name = discovery.get("source")
|
|
987
|
+
chain = inherited_window_chain(source, by_name)
|
|
988
|
+
if chain is not None:
|
|
989
|
+
upstream_name = chain[0]
|
|
934
990
|
upstream = facts.source(upstream_name) if isinstance(upstream_name, str) else {}
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
f"add {column} to {name}'s request.carry_columns so its rows key to the "
|
|
951
|
-
f"partitions of {upstream_name}",
|
|
952
|
-
facts.pointer(name, "/collection/discovery/request/carry_columns"),
|
|
991
|
+
column = window_partition_column(upstream)
|
|
992
|
+
missing_carry = False
|
|
993
|
+
if chain is not None and column is not None:
|
|
994
|
+
for hop in chain[1]:
|
|
995
|
+
if column in row_request_carried(hop):
|
|
996
|
+
continue
|
|
997
|
+
missing_carry = True
|
|
998
|
+
hop_name = str(hop.get("name"))
|
|
999
|
+
suggestions.append(
|
|
1000
|
+
_suggestion(
|
|
1001
|
+
"carry_partition_column",
|
|
1002
|
+
f"add {column} to {hop_name}'s request.carry_columns so its rows key to "
|
|
1003
|
+
f"the partitions of {upstream_name}",
|
|
1004
|
+
facts.pointer(hop_name, "/collection/discovery/request/carry_columns"),
|
|
1005
|
+
)
|
|
953
1006
|
)
|
|
1007
|
+
if not missing_carry and isinstance(upstream_name, str) and upstream:
|
|
1008
|
+
detail = (
|
|
1009
|
+
f"let {upstream_name} refresh as a request window of its own, neither "
|
|
1010
|
+
f"closed nor a page collection, so {name} re-derives only the rows of the "
|
|
1011
|
+
"refreshed partitions"
|
|
1012
|
+
if chain is not None and column is not None
|
|
1013
|
+
else f"make {upstream_name} a request window that replaces whole partitions, "
|
|
1014
|
+
f"so {name} re-derives only the rows of the refreshed partitions"
|
|
954
1015
|
)
|
|
955
|
-
elif isinstance(upstream_name, str) and upstream:
|
|
956
1016
|
suggestions.append(
|
|
957
1017
|
_suggestion(
|
|
958
1018
|
"make_upstream_a_request_window",
|
|
959
|
-
|
|
960
|
-
f"so {name} re-derives only the rows of the refreshed partitions",
|
|
1019
|
+
detail,
|
|
961
1020
|
facts.pointer(upstream_name, "/window"),
|
|
962
1021
|
date_pair_parameters(upstream),
|
|
963
1022
|
)
|
|
@@ -1492,11 +1551,14 @@ __all__ = [
|
|
|
1492
1551
|
"explain_exit_code",
|
|
1493
1552
|
"explain_table_at_studio",
|
|
1494
1553
|
"gated_grammar",
|
|
1554
|
+
"inherited_window_chain",
|
|
1495
1555
|
"mirror_findings",
|
|
1496
1556
|
"registration_gate",
|
|
1497
1557
|
"route_unavailable",
|
|
1558
|
+
"row_request_carried",
|
|
1498
1559
|
"row_request_parameter_names",
|
|
1499
1560
|
"served_capabilities",
|
|
1500
1561
|
"snapshot_sources",
|
|
1501
1562
|
"source_action",
|
|
1563
|
+
"window_partition_column",
|
|
1502
1564
|
]
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/recipe_lint.py
RENAMED
|
@@ -158,6 +158,12 @@ COHERENCE_CREDENTIAL_MODES: frozenset[str] = frozenset({"none", "opaque_referenc
|
|
|
158
158
|
#: ``request`` instead of ``url_column``, on a source declared through this adapter.
|
|
159
159
|
ROW_REQUEST_ADAPTER_ID = "public.https.collection@2.0.0"
|
|
160
160
|
|
|
161
|
+
#: One per-row template token, read left to right: an escaped brace, a ``{name}`` placeholder, a
|
|
162
|
+
#: lone brace, or a run of text with no brace. The registration route and the worker read every
|
|
163
|
+
#: per-row template with this same expression, and no per-row template pattern of
|
|
164
|
+
#: ``recipe.schema.json`` admits a string in which a lone brace is read.
|
|
165
|
+
ROW_TEMPLATE_TOKEN = re.compile(r"\{\{|\}\}|\{([A-Za-z][A-Za-z0-9_]{0,63})\}|[{}]|[^{}]+")
|
|
166
|
+
|
|
161
167
|
#: ``recipe.schema.json#/$defs/collection_revisit``'s bounds on an ``interval``, which the
|
|
162
168
|
#: collection lane's ``MIN_REVISIT_SECONDS`` and ``MAX_REVISIT_SECONDS`` also hold: an hour to a
|
|
163
169
|
#: year. A per-row request admits ``interval`` since Studio 4.14.0 (``CONTRACT.md`` §1.1).
|
|
@@ -226,6 +232,7 @@ def lint_document(document: Mapping[str, Any]) -> list[Finding]:
|
|
|
226
232
|
findings.extend(_sources(document.get("sources")))
|
|
227
233
|
findings.extend(_row_filters(document.get("sources")))
|
|
228
234
|
findings.extend(_row_request_credentials(document.get("sources")))
|
|
235
|
+
findings.extend(_row_request_templates(document.get("sources")))
|
|
229
236
|
findings.extend(_units(document.get("units")))
|
|
230
237
|
findings.extend(_coherence(document, declared=declared))
|
|
231
238
|
findings.extend(_checks(document.get("checks"), declared=declared, grain=_grain(document)))
|
|
@@ -758,6 +765,68 @@ def _row_request_credentials(sources: Any) -> list[Finding]:
|
|
|
758
765
|
return findings
|
|
759
766
|
|
|
760
767
|
|
|
768
|
+
def row_template_is_well_formed(text: str) -> bool:
|
|
769
|
+
"""Whether every brace in one per-row template is doubled or part of a ``{name}`` placeholder.
|
|
770
|
+
|
|
771
|
+
``{{`` is a literal ``{`` and ``}}`` a literal ``}``, read left to right, so ``{{{id}}}`` is a
|
|
772
|
+
literal brace, the ``id`` placeholder and a literal brace.
|
|
773
|
+
"""
|
|
774
|
+
|
|
775
|
+
return all(match.group(0) not in ("{", "}") for match in ROW_TEMPLATE_TOKEN.finditer(text))
|
|
776
|
+
|
|
777
|
+
|
|
778
|
+
def _row_request_templates(sources: Any) -> list[Finding]:
|
|
779
|
+
"""The brace grammar of every per-row request template, held to the schema's.
|
|
780
|
+
|
|
781
|
+
A per-row request renders ``{name}`` from the upstream row in its path, in each query value
|
|
782
|
+
and in each string of its body. A literal brace is written twice, and any other brace is the
|
|
783
|
+
schema's refusal, so each finding carries :data:`DOCUMENT_INVALID`. Header values, query names
|
|
784
|
+
and body keys take no placeholder and are not read here.
|
|
785
|
+
"""
|
|
786
|
+
|
|
787
|
+
if not isinstance(sources, list):
|
|
788
|
+
return []
|
|
789
|
+
findings: list[Finding] = []
|
|
790
|
+
|
|
791
|
+
def check(pointer: str, text: Any) -> None:
|
|
792
|
+
if isinstance(text, str) and not row_template_is_well_formed(text):
|
|
793
|
+
findings.append(
|
|
794
|
+
Finding(
|
|
795
|
+
DOCUMENT_INVALID,
|
|
796
|
+
pointer,
|
|
797
|
+
"holds a brace that is neither doubled nor part of a placeholder; a "
|
|
798
|
+
"placeholder is a parameter name in braces, and a literal brace is written "
|
|
799
|
+
"twice, {{ or }}",
|
|
800
|
+
)
|
|
801
|
+
)
|
|
802
|
+
|
|
803
|
+
def walk(pointer: str, value: Any) -> None:
|
|
804
|
+
if isinstance(value, str):
|
|
805
|
+
check(pointer, value)
|
|
806
|
+
elif isinstance(value, list):
|
|
807
|
+
for position, item in enumerate(value):
|
|
808
|
+
walk(f"{pointer}/{position}", item)
|
|
809
|
+
elif isinstance(value, Mapping):
|
|
810
|
+
for key, item in value.items():
|
|
811
|
+
walk(f"{pointer}/{_escape(str(key))}", item)
|
|
812
|
+
|
|
813
|
+
for index, source in enumerate(sources):
|
|
814
|
+
if not isinstance(source, Mapping):
|
|
815
|
+
continue
|
|
816
|
+
_stated, request = _row_request(source)
|
|
817
|
+
if request is None:
|
|
818
|
+
continue
|
|
819
|
+
at = f"/sources/{index}/collection/discovery/request"
|
|
820
|
+
check(f"{at}/path_template", request.get("path_template"))
|
|
821
|
+
static_query = request.get("static_query")
|
|
822
|
+
for position, pair in enumerate(static_query if isinstance(static_query, list) else ()):
|
|
823
|
+
if isinstance(pair, Mapping):
|
|
824
|
+
check(f"{at}/static_query/{position}/value", pair.get("value"))
|
|
825
|
+
if "body_template" in request:
|
|
826
|
+
walk(f"{at}/body_template", request["body_template"])
|
|
827
|
+
return findings
|
|
828
|
+
|
|
829
|
+
|
|
761
830
|
def _units(units: Any) -> list[Finding]:
|
|
762
831
|
"""Each declared unit's own two members. Whether the column exists is :func:`_coherence`'s."""
|
|
763
832
|
|
|
@@ -1430,8 +1499,10 @@ __all__ = [
|
|
|
1430
1499
|
"MIN_BINS",
|
|
1431
1500
|
"MIN_REVISIT_SECONDS",
|
|
1432
1501
|
"PRESENTATION_BUCKETS",
|
|
1502
|
+
"ROW_TEMPLATE_TOKEN",
|
|
1433
1503
|
"Finding",
|
|
1434
1504
|
"lint_document",
|
|
1435
1505
|
"lint_refusal",
|
|
1506
|
+
"row_template_is_well_formed",
|
|
1436
1507
|
"snapshot_horizon_notes",
|
|
1437
1508
|
]
|
|
@@ -138,7 +138,7 @@ from mostlyright.data_harness.thin.transport import ThinLaneError
|
|
|
138
138
|
#: ``JOB_INVALID`` outright, which in production was every refresh a collection epoch was offered
|
|
139
139
|
#: for rather than only the collection runs. This package must not reach a Studio older than the
|
|
140
140
|
#: commit it pins; ``docs/V4-WORKER-PROTOCOL.md`` states it beside the layout's own ordering rule.
|
|
141
|
-
PINNED_V4_OPENAPI_SOURCE_SHA256 = "
|
|
141
|
+
PINNED_V4_OPENAPI_SOURCE_SHA256 = "afe1b4d7af60c5296f44e00a6bd84dc11a852fcbf4228bbc63a4c2d2b3b00829"
|
|
142
142
|
PINNED_V4_CONTRACT_VERSION = "4.14.0"
|
|
143
143
|
|
|
144
144
|
#: The ``schema_version`` every command body that predates 4.14.0 stamps: ``dataset activity``,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/boundaries.md
RENAMED
|
File without changes
|
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/commands.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/live-run.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/one-install.md
RENAMED
|
File without changes
|
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/promote.md
RENAMED
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/receipts.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/skills/mr-data-build/references/transforms.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/__init__.py
RENAMED
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/agent_protocol.py
RENAMED
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/canonical.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/key_seam.py
RENAMED
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/page_coverage.py
RENAMED
|
File without changes
|
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/session_probes.py
RENAMED
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/skill_assets.py
RENAMED
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/table_manifest.py
RENAMED
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/__init__.py
RENAMED
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/acquire.py
RENAMED
|
File without changes
|
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/activity.py
RENAMED
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/approvals.py
RENAMED
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/categories.py
RENAMED
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/commands.py
RENAMED
|
File without changes
|
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/download.py
RENAMED
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/narrative.py
RENAMED
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/parity.py
RENAMED
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/probe.py
RENAMED
|
File without changes
|
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/propose.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/research.py
RENAMED
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/router.py
RENAMED
|
File without changes
|
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/runs.py
RENAMED
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/session.py
RENAMED
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/stream.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/transport.py
RENAMED
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/user_agent.py
RENAMED
|
File without changes
|
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/v4_catalog.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/v4_datasets.py
RENAMED
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/v4_handoff.py
RENAMED
|
File without changes
|
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/v4_public.py
RENAMED
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/v4_query.py
RENAMED
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/v4_reader.py
RENAMED
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/v4_runs.py
RENAMED
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/v4_secrets.py
RENAMED
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/v4_stream.py
RENAMED
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/v4_tables.py
RENAMED
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/thin/vocabulary.py
RENAMED
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/ux/__init__.py
RENAMED
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/ux/attendance.py
RENAMED
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/ux/clarification.py
RENAMED
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/ux/cloud_auth.py
RENAMED
|
File without changes
|
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/ux/commands/auth.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/ux/credentials.py
RENAMED
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/ux/login.py
RENAMED
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/ux/path_kind.py
RENAMED
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/ux/plain_file.py
RENAMED
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/ux/remediation.py
RENAMED
|
File without changes
|
{mostlyright_data-0.26.0 → mostlyright_data-0.26.1}/src/mostlyright/data_harness/ux/render.py
RENAMED
|
File without changes
|